如何将对话框的OK按钮连接到Qt主窗口中的QAction按钮,然后启动程序的执行



我是Qt的初学者,花了两天时间试图找出问题所在,但遗憾的是我没能找到,我真的很感谢你的帮助。我在主窗口中有一个Set Parameters,当点击它时,它会启动一个对话框,允许用户输入x和y的值。我试图连接对话框中点击按钮OK的信号,以连接到主窗口上的QAction Start按钮,点击该启动按钮后,程序运行,这将乘以两个数字。

错误:静态断言失败:插槽需要的参数比信号提供的参数多。信号和插槽参数不兼容

我在这里添加了我的程序代码。

主窗口.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
```

主窗口.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);
}
```

对话框设置参数.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

我很抱歉对这段代码进行了粗略的审查,但这段代码只是由于不了解C++和Qt的工作原理而造成的混乱。缺乏对C++的理解,因为您不了解执行顺序、内存初始化以及用局部变量隐藏成员变量。以及缺乏对Qt的理解,因为你不了解插槽和信号是如何工作的。这个代码或多或少只是一堆随机的代码,没有任何深入的思考。至少有四个关键问题(我希望我没有忽视更多(。可能还有很多次要的/风格上的。当你写作时,你是一个初学者,所以这没关系,但在你深入到更复杂的东西之前,你需要学习更多的基础知识。

MainWindow构造函数中的dialogParams未初始化,这是未定义的行为。因此,连接根本不起作用。
  • 您在on_actionSet_Parameters_triggered中创建dialogParams作为局部变量,它不会初始化成员指针MainWindow::dialogParams。它们只是两个不同的变量。此外,在主窗口关闭之前,创建的对话框对象不会被删除。这实际上是一种内存泄漏。

  • on_OKbtn_clicked()是一个插槽,而不是一个信号,因此您无法将其作为信号连接。

  • 我看不到从QAction::triggered到任何插槽的任何连接。如果您希望自动连接到on_actionStart_triggered(x, y),那么它将不起作用,因为它的参数不匹配。

  • 这四个中的任何一个都将导致此程序无法运行。你需要修复所有的问题。因此,您需要覆盖代码的主要部分,并记住我刚才指出的所有问题。

    还有一些建议:

    1. 始终检查连接是否成功,如果不成功则断言(在调试模式下(。理想情况下,将Qt::UniqueConnection参数添加到connect中,因为它通常是您实际想要的
    2. 永远不要依赖基于信号/插槽名称匹配的自动连接。这太脆弱了。这是Qt最糟糕的设计缺陷之一,甚至存在这样的东西
    3. 使用QDialog::accepted信号表示对话框正常
    4. 尽量避免QtDesigner和UI文件成为瘟疫。他们是邪恶的。如果你是初学者,它们只会让你的学习更加困难。如果你进步了,他们会让你的工作更加努力。只需学习在代码中设置所有UI即可。它看起来像是更多的手工工作,但它有很多好处。。。实际上,这是更少的工作,而不是更多

    最新更新