Co zrobić, aby wyemitowanie sygnału stworzyło nowe okno?

0

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.

2

Podpinasz slot tworzący nowe okno.

0

Jeśli chodzi Ci o okno modalne to użyj QDialog.

2

W Qt5 masz C++11 więc można nawet użyć lambdy.

0

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.

2

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ł.

0

Ewentualnie można też uzyć QApplication::activeWindow()

0

@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.

2
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)));
    });
}
…


1

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 );
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1