Co zrobić, aby w Qt po emisji sygnału np. wciśnięcie przycisku, postało jakieś nowe okno? Próbowałem zrobić własną klasę ona i użyć metody show(), ale to nie wychodziło.
Podpinasz slot tworzący nowe okno.
Jeśli chodzi Ci o okno modalne to użyj QDialog
.
W Qt5 masz C++11 więc można nawet użyć lambdy.
Ten problem udało mi się rozwiązać dodając nową klasę formularza do projektu. Tylko nie wiem co zrobić, aby nowe okno mogło oddziaływać na główne, czyli np. żeby wciśnięcie przycisku w dodatkowym oknie zmieniało tytuł głównego okna. Wiem, że do tego trzeba connecta użyć, ale dodatkowe okno nie ma dostępu do obiektu tego głównego okna.
W Qt na w większości wypadków odpowiedzią na takie problemy są sygnały i sloty.
@Mokrowski im mniej klasy są siebie na wzajem świadome tym lepiej, więc przekazywanie wskaźnika to zły pomysł.
Ewentualnie można też uzyć QApplication::activeWindow()
@Mokrowski: @MarekR22: Tylko chyba w przypadku przekazania wskaźnika, do okna, trzeba by zmodyfikować klasę okna MainWindow tak, aby wskaźnik w nim *ui.
Kod tego co zrobiłem do tej pory wygląda tak.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "testwindow.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
friend testWindow;
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
testWindow t;
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
testwindows.h
#ifndef TESTWINDOW_H
#define TESTWINDOW_H
#include <QMainWindow>
namespace Ui {
class testWindow;
}
class testWindow : public QMainWindow
{
Q_OBJECT
public:
explicit testWindow(QWidget *parent = 0);
~testWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::testWindow *ui;
};
#endif // TESTWINDOW_H
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(&t, &QWidget::close , [&]{
this->setWindowTitle("test123456789");
});
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
t.show();
}
testwindow.cpp
#include "testwindow.h"
#include "ui_testwindow.h"
testWindow::testWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::testWindow)
{
ui->setupUi(this);
}
testWindow::~testWindow()
{
delete ui;
}
void testWindow::on_pushButton_clicked()
{
//
}
Klasy okien wygenerowało odpowiednie narzędzie w Qt. Jak do czegoś takiego mógłby wyglądać connect czy to przekazanie wskaźnika? Ja próbowałem to zrobić na dużo sposobów i nic z tego nie wychodziło.
void testWindow::on_pushButton_clicked()
{
setNewTitle(ui->titleLineEdit->text());
}
void testWindow::setNewTitle(const QString& title)
{
if (newTitle != title)
{
newTitle = title;
emit newTitleChanged(title);
}
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(&t, SIGNAL(newTitleChanged(QString)), // trzymanie okna przez wartość to niezbyt dobre rozwiazanie
this, SLOT(setWindowTitle(QString)));
});
}
…
A wersja z dialogiem może wyglądać tak (wersja bez formularzy)
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class MainWindow : public QMainWindow
{
Q_OBJECT
private:
QString originalTitle;
QWidget* mainWidget;
protected slots:
void OnEditClicked( bool checked = false );
void OnResetClicked( bool checked = false );
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "mainwindow.h"
#include <QPushButton>
#include <QBoxLayout>
#include "mydialog.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
originalTitle = QString::fromUtf8( "Oryginalny tytuł okna" );
setWindowTitle( originalTitle );
mainWidget = new QWidget( this );
QVBoxLayout* main_layout = new QVBoxLayout;
QPushButton* btnEdit = new QPushButton( QString::fromUtf8( "Otwórz dialog" ), this );
connect( btnEdit, &QPushButton::clicked, this, &MainWindow::OnEditClicked );
main_layout->addStretch( 1 );
QPushButton* btnReset = new QPushButton( QString::fromUtf8( "Reset" ), this );
connect( btnReset, &QPushButton::clicked, this, &MainWindow::OnResetClicked );
main_layout->addWidget( btnEdit );
main_layout->addWidget( btnReset );
main_layout->addStretch( 1 );
mainWidget->setLayout( main_layout );
setCentralWidget( mainWidget );
}
void MainWindow::OnEditClicked( bool checked )
{
Q_UNUSED( checked );
MyDialog* dialog = new MyDialog( mainWidget );
dialog->setModal( false );
connect( dialog, &MyDialog::ChangeTitle, this, &MainWindow::setWindowTitle );
dialog->show();
}
void MainWindow::OnResetClicked( bool checked )
{
Q_UNUSED( checked );
setWindowTitle( originalTitle );
}
MainWindow::~MainWindow()
{
}
MyDialog.h
#ifndef MYDIALOG_H
#define MYDIALOG_H
#include <QDialog>
class QLineEdit;
class MyDialog : public QDialog
{
Q_OBJECT
private:
QLineEdit* titleInput;
protected:
void SetupDialog();
protected slots:
void OnTextChanged( const QString& text );
signals:
void ChangeTitle( const QString& text );
public:
explicit MyDialog( QWidget* parent = Q_NULLPTR );
};
#endif // MYDIALOG_H
MyDialog.cpp
#include "mydialog.h"
#include <QBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
MyDialog::MyDialog( QWidget* parent ) : QDialog( parent )
{
setWindowTitle( QString::fromUtf8( "Edycja tytułu okna" ) );
SetupDialog();
}
void MyDialog::SetupDialog()
{
QVBoxLayout* main_layout = new QVBoxLayout;
main_layout->addWidget( new QLabel( QString::fromUtf8( "Nowy tytuł" ), this ) );
titleInput = new QLineEdit( this );
main_layout->addWidget( titleInput, 1 );
connect( titleInput, &QLineEdit::textChanged, this, &MyDialog::OnTextChanged );
setLayout( main_layout );
}
void MyDialog::OnTextChanged( const QString& text )
{
emit ChangeTitle( text );
}