How to connect an OK button of a dialog to an QAction button in the MainWindow in Qt, which then launch the execution of a programme?

Viewed 47

I am a beginner in Qt and I tried for two days to find out what's wrong unfortunately I couldn't, I would really appreciate your help. I have a Set Parameters in the MainWindow, when clicking on it it launch a dialog, that allow a user to input values for x and y. I am trying to connect the signal of clicking the button OK from the dialog to connect to QAction Start button on the MainWindow, and after clicking that start button the program run, which multiply two numbers.

The errors: Static assertion failed: The slot requires more arguments than the signal provides. Signal and slot arguments are not compatible

I added here the code of my program.

mainwindow.h

```
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "dialogsetparams.h"
#include <QPushButton>
#include <QAction>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_actionSet_Parameters_triggered();

    void on_actionStart_triggered(double x, double y);

signals:
    void multiplySignal(double x, double y);

private:
    Ui::MainWindow *ui;

    DialogSetParams *dialogParams;
};
#endif // MAINWINDOW_H

```

mainwindow.cpp

```
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dialogsetparams.h"
#include "multxy.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // connect signal OK clicked from dialog to &QAction Start buttun in mainwindow
    connect(dialogParams, &DialogSetParams::on_OKbtn_clicked, ui->actionStart, &QAction::triggered);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_actionSet_Parameters_triggered()
{
    DialogSetParams *dialogParams = new DialogSetParams(this);
    dialogParams->show();
}

void MainWindow::on_actionStart_triggered(double x, double y)
{
    // create an instance of class BspMembraneSurf when Start button triggered
    Multxy* multOp = new Multxy();
    multOp->computexy(x, y);
}

```

dialogsetparams.h

```
#ifndef DIALOGSETPARAMS_H
#define DIALOGSETPARAMS_H
#include <QDialog>
#include <QObject>

namespace Ui {
class DialogSetParams;
}

class DialogSetParams : public QDialog
{
    Q_OBJECT

public:
    explicit DialogSetParams(QWidget *parent = nullptr);
    ~DialogSetParams();

    double x;
    double y;

public slots:
    void on_OKbtn_clicked();

signals:
    void setParams(double x, double y);

private:
    Ui::DialogSetParams *ui;

};
#endif // DIALOGSETPARAMS_H

dialogsetparams.cpp

    ```
    #include "dialogsetparams.h"
    #include "ui_dialogsetparams.h"
    #include <QPushButton>
    #include <QDebug>
    
    DialogSetParams::DialogSetParams(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::DialogSetParams)
    {
        ui->setupUi(this);
    
        // connect clicked signal to OK button slot
        connect(ui->OKbtn, &QPushButton::clicked, this, &DialogSetParams::on_OKbtn_clicked);
    
        emit setParams(x, y);
    }
    
    DialogSetParams::~DialogSetParams()
    {
        delete ui; 
    }
    
    void DialogSetParams::on_OKbtn_clicked()
    {
        // Get user input from dialog
        x = ui->xDoubleSpinBox->value();
        y = ui->yDoubleSpinBox->value();
    
        accept();
    }
    
    ```


[Set Parameters][1]
[dialog][2]
[errors][3]

  [1]: https://i.stack.imgur.com/KuVbh.png
  [2]: https://i.stack.imgur.com/Rvp8e.png
  [3]: https://i.stack.imgur.com/CHzJf.png
1 Answers

I am sorry for quite a rough review of this code, but this code is just a mess caused by lack of understanding how C++ and Qt work. Lack of understanding of C++ because you do not understand the order of execution, initialization of memory and shadowing of member variables with local variables. And lack of understanding of Qt because you do not understand how slots and signals work. This code is more or less just a random pile of code without any deeper thought. There are at least four critical problems (and I hope I have not overlooked more). And probably many more minor/stylistic ones. As you write you are a beginner so that is OK but you need to learn more fundamentals before you dive into more complex stuff.

  1. dialogParams in MainWindow constructor is uninitialized, which is undefined behavior. Therefore the connection does not work at all.

  2. You create dialogParams in on_actionSet_Parameters_triggered as a local variable, which does not initialize the member pointer MainWindow::dialogParams. They are simply two different variables. Moreover the created dialog objects do not get deleted until the MainWindow gets closed. It is in fact a kind of memory leak.

  3. on_OKbtn_clicked() is a slot and not a signal so you cannot connect it as signal.

  4. I do not see any connection from QAction::triggered to any slot. If you expect automatic connection to on_actionStart_triggered(x, y) then it will not work because it has parameter mismatch.

Any single of these four will cause that this program will not work. You need to fix all of them. So you need to overwrite major part of your code and keep in mind all the issues I have just pointed out.

And some more pieces of advice:

  1. Always check whether the connection succeeded and assert (in debug mode) if not. And ideally add Qt::UniqueConnection parameter to connect, because it is usually what you actually want.
  2. Never ever rely on automatic connections based on signal/slot name matching. This is too fragile. It is one of the worst Qt design flaws that such a thing even exists.
  3. Use QDialog::accepted signal to signify that the dialog was OKayed.
  4. Try to avoid QtDesigner and UI files as plague. They are evil. They only make your learning more difficult if you are a beginner. And they make your work harder if you are advanced. Just learn to set up all your UI in code. It looks like more manual work but it has so many benefits... and it is actually less work, not more.
Related