Button im zweiten Fenster führt Funktion im ersten Fenster aus



  • Hallo,
    es wäre schön, wenn mich jemand bei meinen Problem unterstützen könnte.
    Ich würde gern durch das Bestätigen eines Button in einem zweiten Fenster(QDialog) eine Funktion ausführen, die mir im ersten Fenster in ein QListWidget schreibt.
    main.cpp

    #include "mainwindow.h"
    #include "secdia.h"
    #include "ui_secdia.h"
    #include "ui_mainwindow.h"
    #include <QApplication>
    #include <QPushButton>
    #include <QLayout>
    #include <QTextEdit>
    #include <QMessageBox>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        MainWindow w;
        w.show();
    
        //connect(, SecDia::on_ButtonOk_clicked())
        //test();
    
        return a.exec();
    }
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "secdia.h"
    #include "ui_mainwindow.h"
    #include "ui_secdia.h"
    #include <QMessageBox>
    #include <QLabel>
    #include <QPushButton>
    
    
    static int i = 0;
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
    
        ui->setupUi(this);
        //connect(ui->cmdHallo, SIGNAL(clicked()), this, SLOT(test()));
        connect(sec->ButtonOk, SIGNAL(clicked()), this, SLOT(test()));
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    
    }
    
    void MainWindow::on_cmdHallo_clicked()
    {
        //QMessageBox *myMessageBox=new QMessageBox(this);
       // myMessageBox->setText("Hallo Welt");
        //myMessageBox->show();
    
        ui->lblText->setText("Hello");
    
    
    }
    
    void MainWindow::on_actionBeenden_triggered()
    {
        this->close();
    }
    
    void MainWindow::on_actionNeu_triggered()
    {
    
    
        // test();
        sec = new SecDia(this);
        sec->show();
    }
    
    void MainWindow::test()
    {
    
        ui->listWidget->addItem(QString::number(i));
        i++;
    }
    
    

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QSignalMapper>
    #include "secdia.h"
    #include "ui_mainwindow.h"
    #include "ui_secdia.h"
    #include <QPushButton>
    
    
    class QPushButton;
    
    class SecDia;
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    
    private slots:
        void on_actionBeenden_triggered();
    
        void on_actionNeu_triggered();
    
        void on_cmdHallo_clicked();
    
    public slots:
        void test();
    
    private:
        Ui::MainWindow *ui;
        SecDia *sec;
    
    
    
    
    };
    
    #endif // MAINWINDOW_H
    
    

    secdia.cpp

    #include "secdia.h"
    #include "ui_secdia.h"
    #include "mainwindow.h"
    #include <QMessageBox>
    #include <QLabel>
    #include <QPushButton>
    
    
    
    SecDia::SecDia(QWidget *parent) :
        QDialog(parent),
        sec(new Ui::SecDia)
    {
        sec->setupUi(this);
    
        connect(sec->ButtonOk, SIGNAL(clicked()), this, SLOT(test()));
    }
    
    SecDia::~SecDia()
    {
        delete sec;
    }
    
    void SecDia::on_ButtonAbbrechen_2_clicked()
    {
        this->close();
    }
    
    void SecDia::on_ButtonOk_clicked()
    {
        this->close();
    
    
    }
    

    secdia.h

    #ifndef SECDIA_H
    #define SECDIA_H
    
    
    #include "ui_secdia.h"
    #include <QDialog>
    
    class QPushButton;
    
    class MainWindow;
    
    namespace Ui {
    class SecDia;
    
    }
    
    class SecDia : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit SecDia(QWidget *parent = nullptr);
        ~SecDia();
    
    
    private slots:
        void on_ButtonAbbrechen_2_clicked();
    
    public slots:
        void on_ButtonOk_clicked();
    
    private:
        Ui::SecDia *sec;
    
    };
    
    #endif // SECDIA_H
    

    Mein Ansatz ist in der mainwindow.cpp dargestellt. Ich hatte versucht das Signal des ButtonOk aus dem zweiten Fenster herauszufiltern. Das Problem ist, dass das erste Fenster diesen Button nicht erkennt.

    Ich hoffe ihr könnt mir weiter helfen.



  • @rs_freak93

    Eventuell kannst du dir einmal die verschiedenen Dialog-Beispiele zu Gemüte führen.

    Dialoge kannst du oft auch mit exec anzeigen und ausführen. Allerdings sind andere Fenster nicht zugreifbar bis du den Dialog geschlossen hast. Standard-Dialoge mit OK und Cancel-Buttons geben eventuell einen Return-Wert Da musst du halt schauen.

    In deinem Falle ist eventuell ein Signal im zweiten Dialog besser. Dieses kann über den Slot on_ButtonOk_clicked() ausgesandt werden.

    public:
        explicit SecDia(QWidget *parent = nullptr);
        ~SecDia();
    
    signals:
         void sigOkPressed();
    
    private slots:
        void on_ButtonAbbrechen_2_clicked();
    
    public slots:
        void on_ButtonOk_clicked();
    
    private:
    

    und

    void SecDia::on_ButtonOk_clicked()
    {
        emit sigOkPressed();
    
        this->close();
    }
    
    SecDia::SecDia(QWidget *parent) :
        QDialog(parent),
        sec(new Ui::SecDia)
    {
        sec->setupUi(this);
    
        connect(sec, SIGNAL(sigOkPressed), this, SLOT(test()));
    }
    
    

    Schaue einmal ob das läuft.



  • @koahnig vielen Dank erst einmal für deine schnelle Antwort.
    Leider muss ich dir mitteilen, dass das nicht funktioniert. Es erscheint folgende Fehlermeldung: no matching member function for call to 'connect'.
    Eine andere Idee?



  • @rs_freak93

        connect(sec, SIGNAL(sigOkPressed()), this, SLOT(test()));
    

    Sorry ich verwende mittlerweile die Functor-Methode. Ausserdem ist mir nicht aufgefallen, dass dieses connect im falschen Contructor ist. Das funktioniert an der Stelle sowieso nicht.

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        connect(sec, SIGNAL(sigOkPressed()), this, SLOT(test()));
    }
    
    SecDia::SecDia(QWidget *parent) :
        QDialog(parent),
        sec(new Ui::SecDia)
    {
        sec->setupUi(this);
    }
    

    Bzw bekommst du mit der Functor-Methode schon compile-Fehler und musst nicht erst auf die Ausführung warten:

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        connect(sec, &SecDia::sigOkPressed, this, &MainWindow::test);
    }
    

    So sollte es funktionieren. Musst du aber erst einmal ausprobieren. Da sind doch ein paar Sachen durch deine Versuche übrig geblieben.



  • Das sieht schon mal ganz gut aus. Die Methode gefällt mir von den Syntax auch sehr gut. Es kommt auch keine Fehlermeldung mehr und das Programm startet. Allerdings wird die Funktion nicht ausgeführt. In der Konsole unter erscheint nur QObject::connect: invalid null parameter.
    Wenn ich jetzt vor dem connect noch ein QObject mache, stürzt das Programm ab.
    Woran könnte es jetzt noch liegen?



  • @rs_freak93

    Beim connect ist das Object noch nicht existent und der Pointer enthält wohl Null.

    Ich bin davon ausgegangen, dass in ui->setupUi schon das Object angelegt wird. Diese Annahme ist falsch.

    void MainWindow::on_actionNeu_triggered()
    {
        sec = new SecDia(this);
    
        connect(sec, &SecDia::sigOkPressed, this, &MainWindow::test);
    
        sec->show();
    }
    

    Verschiebe das connect an diese Stelle.

    Grundsätzlich würde ich dir ein paar Grundlagen der Programmierung in C++ empfehlen. Ansonsten wirst du nicht lange, wenn überhaupt, Freude an der Erstellung von Applikationen mit und ohne Qt haben.



  • Das hat geklappt. Vielen Dank für deine Hilfe.
    Ich lernte die Programmiersprache C in Verbindung mit Microcontrollern. Dieses Projekt wollte ich dafür nutzen, um C++ und Qt zu erlernen.


Log in to reply