如何将信号从线程连接到插槽

How to connect a signal from a thread to a slot?

本文关键字:连接 插槽 线程 信号      更新时间:2023-10-16

我只想做的是将线程内的信号连接到主线程中的插槽以处理UI更改。

这基本上是我的线程的当前状态,没有什么花哨的,但它仅用于测试目的 atm:

// synchronizer.h
class Synchronizer : public QObject
{
    Q_OBJECT
public:
    Synchronizer();
signals:
    void newConnection(std::wstring id);
private:
    QTimer timer;
private slots:
    void synchronize();
}
// synchronizer.cpp
Synchronizer::Synchronizer()
{
    connect(&timer, SIGNAL(timeout()), this, SLOT(synchronize()));
    timer.start();
}
void Synchronizer::synchronize()
{
    emit newConnection(L"test");
}

以下是我的主窗口的外观:

// mainwindow.h
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private:
    Ui::MainWindow *ui;
    Synchronizer synchronizer;
private slots:
    void addConnection(std::wstring id);
}
// mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(&synchronizer, SIGNAL(newConnection(std::wstring)),
            this, SLOT(addConnection(std::wstring)));
    QThread *thread = new QThread;
    // The problems starts here?
    synchronizer.moveToThread(thread);
    thread->start();
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::addConnection(std::wstring id)
{
    // Add a new connection to QListWidget
    ui->connectionList(QString::fromStdWString(id));
}

如果我删除那里的行:

synchronizer.moveToThread(thread);
thread->start();

一切似乎都按预期工作,即每秒都会向 QListWidget 添加一个新项目,但是一旦我将同步器对象移动到线程,它就会停止工作。我认为它与连接上下文有关,但我不确定应该如何实现这样的事情,因为我对 Qt 很陌生。

在这种情况下,似乎只是因为我使用 std::wstring 作为信号中的参数,而没有先注册类型,然后在将以下行qRegisterMetaType<std::wstring>("std::wstring");添加到代码后,一切都按预期工作。

如果我更仔细地阅读输出控制台,我会毫不费力地解决问题,因为它清楚地表明:
QObject::connect: Cannot queue arguments of type 'std::wstring'

所以简单地说,阅读编译器输出,不要像我一样愚蠢:)