简体   繁体   English

Qt - 在触发动作中连接信号/插槽

[英]Qt - connecting a signal/slot in a triggered action

I'm using Qt 5 on a Windows and building a GUI App with multiple QDialog classes. 我在Windows上使用Qt 5并使用多个QDialog类构建GUI应用程序。 I am trying to connect a signal from a QDialog in a triggered action of the QMainWindow class after instances of both have been created. 在创建两者的实例后,我试图在QMainWindow类的触发动作中连接来自QDialog的信号。 I have read the documentation on Qt here: http://doc.qt.io/qt-4.8/signalsandslots.html and here: https://wiki.qt.io/New_Signal_Slot_Syntax . 我在这里阅读了关于Qt的文档: http//doc.qt.io/qt-4.8/signalsandslots.html和这里: https//wiki.qt.io/New_Signal_Slot_Syntax I have also read through many questions on stackoverflow that have helped correct some of the initial errors I was getting, but haven't helped me solve this problem. 我还阅读了很多关于stackoverflow的问题,这些问题帮助纠正了我得到的一些初始错误,但没有帮助我解决这个问题。

The error I keep getting is: 我一直得到的错误是:

"expected primary-expression before ',' token" “在'之前预期的初级表达','令牌”

I have tried both the old syntax for connect 我已经尝试了连接的旧语法

connect(sender, SIGNAL (valueChanged(QString,QString)),
 receiver, SLOT (updateValue(QString)) );

and the new syntax (which is shown in the .cpp file below) 和新语法(显示在下面的.cpp文件中)

connect(sender, &Sender::valueChanged,
 receiver, &Receiver::updateValue );

The MainWindow is created in the main.cpp and the 2nd dialog is created on_action_someAction_triggered(), so I know that the instances I am referencing exist. MainWindow在main.cpp中创建,第二个对话框在on_action_someAction_triggered()上创建,所以我知道我引用的实例存在。 Is there a better way for me to connect the SIGNAL and the SLOT? 有没有更好的方法来连接SIGNAL和SLOT?

Here is the code I am working with (minus the extra unrelated code). 这是我正在使用的代码(减去额外的无关代码)。

mainwindow .h: 主窗口.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 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 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 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

}

I think, the code should be 我认为,代码应该是

sDialog = new shipdia(this); 
QObject::connect(sDialog,               
        &shipdia::sendShip,this,&MainWindow::loadSelectedShip);

and it should be placed in the constructor of the MainWindow, right after ui->setupUi(this); 它应该放在MainWindow的构造函数中,就在ui-> setupUi(this)之后; and the on_actionNew_Ship_triggered() function should look like this: 并且on_actionNew_Ship_triggered()函数应该如下所示:

void MainWindow::on_actionNew_Ship_triggered()
{
    sDialog ->show();
}

In your original code, a new instance of shipdia will be created everytime the on_actionNew_Ship_triggered() is called. 在原始代码中,每次调用on_actionNew_Ship_triggered()时都会创建一个新的shipdia实例。 That should be avoided. 应该避免这种情况。

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM