Qt - 在触发动作中连接 signal/slot
Qt - connecting a signal/slot in a triggered action
我在 Windows 上使用 Qt 5 并使用多个 QDialog class 构建一个 GUI 应用程序。在创建两个实例后,我试图在 QMainWindow class 的触发操作中连接来自 QDialog 的信号。我在这里阅读了关于 Qt 的文档:http://doc.qt.io/qt-4.8/signalsandslots.html and here: https://wiki.qt.io/New_Signal_Slot_Syntax。我还通读了许多关于 Whosebug 的问题,这些问题帮助纠正了我最初遇到的一些错误,但没有帮助我解决这个问题。
我不断收到的错误是:
"expected primary-expression before ',' token"
我已经尝试过连接的旧语法
connect(sender, SIGNAL (valueChanged(QString,QString)),
receiver, SLOT (updateValue(QString)) );
和新语法(显示在下面的 .cpp 文件中)
connect(sender, &Sender::valueChanged,
receiver, &Receiver::updateValue );
MainWindow 在 main.cpp 中创建,第二个对话框在 on_action_someAction_triggered() 中创建,所以我知道我引用的实例存在。有没有更好的方式连接SIGNAL和SLOT?
这是我正在使用的代码(减去额外的无关代码)。
主窗口.h:
#include <QMainWindow>
#include "shipdia.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void loadSelectedShip(QString shipName);
private slots:
void on_actionNew_Ship_triggered();
private:
Ui::MainWindow *ui;
shipdia *sDialog;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTextStream>
#include <QObject>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_actionNew_Ship_triggered()
{
sDialog = new shipdia(this);
QObject::connect(&shipdia, //this is were I attempt to
&shipdia::sendShip, //connect the signal/slot
this,&MainWindow::loadSelectedShip); //but always get an error
sDialog ->show();
}
void MainWindow::loadSelectedShip(QString shipName)
{
... do something ... //this code works, but the signal is never received
}
qdialog.h
#ifndef SHIPDIA_H
#define SHIPDIA_H
#include "functions.h"
#include <QDialog>
namespace Ui {
class shipdia;
}
class shipdia : public QDialog
{
Q_OBJECT
public:
explicit shipdia(QWidget *parent = 0);
~shipdia();
private slots:
void on_pushButton_2_clicked();
signals:
void sendShip(QString shipName);
private:
Ui::shipdia *ui;
};
#endif // SHIPDIA_H
qdialog.cpp
#include "shipdia.h"
#include "ui_shipdia.h"
#include <QObject>
#include <QMessageBox>
#include <QTextStream>
#include <QDir>
shipdia::shipdia(QWidget *parent) :
QDialog(parent),
ui(new Ui::shipdia)
{
ui->setupUi(this);
}
shipdia::~shipdia()
{
delete ui;
}
void shipdia::sendSelectedShip(QString shipName)
{
emit sendShip(shipName); //I previously just emitted sendSelectedShip,
//but separating the function did not fix it.
}
void shipdia::on_pushButton_2_clicked()
{
//Code below functions up to next comment
QString shipName = ui->line_23->text();
shipName = QDir::currentPath() + "/shipFolder/" + shipName + ".txt";
QFile shipFile(shipName);
QStringList stringList;
if (shipFile.open(QIODevice::ReadOnly))
{
QTextStream in(&shipFile);
while(!in.atEnd())
{
QString line = in.readLine();
if(line.isNull())
break;
else
stringList.append(line);
}
shipFile.close();
}
//Code above functions ^
sendSelectedShip(shipName); //this line does not produce an error
}
我觉得,代码应该是
sDialog = new shipdia(this);
QObject::connect(sDialog,
&shipdia::sendShip,this,&MainWindow::loadSelectedShip);
它应该放在 MainWindow 的构造函数中,就在 ui->setupUi(this) 之后; on_actionNew_Ship_triggered() 函数应该如下所示:
void MainWindow::on_actionNew_Ship_triggered()
{
sDialog ->show();
}
在您的原始代码中,每次调用 on_actionNew_Ship_triggered() 时都会创建一个新的 shipdia 实例。应该避免这种情况。
希望对您有所帮助。
我在 Windows 上使用 Qt 5 并使用多个 QDialog class 构建一个 GUI 应用程序。在创建两个实例后,我试图在 QMainWindow class 的触发操作中连接来自 QDialog 的信号。我在这里阅读了关于 Qt 的文档:http://doc.qt.io/qt-4.8/signalsandslots.html and here: https://wiki.qt.io/New_Signal_Slot_Syntax。我还通读了许多关于 Whosebug 的问题,这些问题帮助纠正了我最初遇到的一些错误,但没有帮助我解决这个问题。
我不断收到的错误是:
"expected primary-expression before ',' token"
我已经尝试过连接的旧语法
connect(sender, SIGNAL (valueChanged(QString,QString)),
receiver, SLOT (updateValue(QString)) );
和新语法(显示在下面的 .cpp 文件中)
connect(sender, &Sender::valueChanged,
receiver, &Receiver::updateValue );
MainWindow 在 main.cpp 中创建,第二个对话框在 on_action_someAction_triggered() 中创建,所以我知道我引用的实例存在。有没有更好的方式连接SIGNAL和SLOT?
这是我正在使用的代码(减去额外的无关代码)。
主窗口.h:
#include <QMainWindow>
#include "shipdia.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void loadSelectedShip(QString shipName);
private slots:
void on_actionNew_Ship_triggered();
private:
Ui::MainWindow *ui;
shipdia *sDialog;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTextStream>
#include <QObject>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_actionNew_Ship_triggered()
{
sDialog = new shipdia(this);
QObject::connect(&shipdia, //this is were I attempt to
&shipdia::sendShip, //connect the signal/slot
this,&MainWindow::loadSelectedShip); //but always get an error
sDialog ->show();
}
void MainWindow::loadSelectedShip(QString shipName)
{
... do something ... //this code works, but the signal is never received
}
qdialog.h
#ifndef SHIPDIA_H
#define SHIPDIA_H
#include "functions.h"
#include <QDialog>
namespace Ui {
class shipdia;
}
class shipdia : public QDialog
{
Q_OBJECT
public:
explicit shipdia(QWidget *parent = 0);
~shipdia();
private slots:
void on_pushButton_2_clicked();
signals:
void sendShip(QString shipName);
private:
Ui::shipdia *ui;
};
#endif // SHIPDIA_H
qdialog.cpp
#include "shipdia.h"
#include "ui_shipdia.h"
#include <QObject>
#include <QMessageBox>
#include <QTextStream>
#include <QDir>
shipdia::shipdia(QWidget *parent) :
QDialog(parent),
ui(new Ui::shipdia)
{
ui->setupUi(this);
}
shipdia::~shipdia()
{
delete ui;
}
void shipdia::sendSelectedShip(QString shipName)
{
emit sendShip(shipName); //I previously just emitted sendSelectedShip,
//but separating the function did not fix it.
}
void shipdia::on_pushButton_2_clicked()
{
//Code below functions up to next comment
QString shipName = ui->line_23->text();
shipName = QDir::currentPath() + "/shipFolder/" + shipName + ".txt";
QFile shipFile(shipName);
QStringList stringList;
if (shipFile.open(QIODevice::ReadOnly))
{
QTextStream in(&shipFile);
while(!in.atEnd())
{
QString line = in.readLine();
if(line.isNull())
break;
else
stringList.append(line);
}
shipFile.close();
}
//Code above functions ^
sendSelectedShip(shipName); //this line does not produce an error
}
我觉得,代码应该是
sDialog = new shipdia(this);
QObject::connect(sDialog,
&shipdia::sendShip,this,&MainWindow::loadSelectedShip);
它应该放在 MainWindow 的构造函数中,就在 ui->setupUi(this) 之后; on_actionNew_Ship_triggered() 函数应该如下所示:
void MainWindow::on_actionNew_Ship_triggered()
{
sDialog ->show();
}
在您的原始代码中,每次调用 on_actionNew_Ship_triggered() 时都会创建一个新的 shipdia 实例。应该避免这种情况。
希望对您有所帮助。