C++ 如何将信号从线程连接到插槽?
我只想将线程内的信号连接到主线程中的插槽,以处理UI更改 这基本上是我线程的当前状态,没有什么特别之处,只是出于测试目的:C++ 如何将信号从线程连接到插槽?,c++,multithreading,qt,C++,Multithreading,Qt,我只想将线程内的信号连接到主线程中的插槽,以处理UI更改 这基本上是我线程的当前状态,没有什么特别之处,只是出于测试目的: // synchronizer.h class Synchronizer : public QObject { Q_OBJECT public: Synchronizer(); signals: void newConnection(std::wstring id); private: QTimer timer; private sl
// 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添加一个新项,但一旦我将synchronizer对象移动到线程,它就会停止工作。我认为这与连接上下文有关,但我不确定这样的事情应该如何实现,因为我对Qt很陌生。在这种情况下,问题似乎只是因为我在信号中使用std::wstring作为参数,而没有先注册类型,然后添加以下行
qRegisterMetaType(“std::wstring”)代码>对于代码,一切都按预期进行
如果我能更仔细地阅读输出控制台,我会毫不费力地解决这个问题,因为它清楚地说明:
QObject::connect:无法对类型为'std::wstring'的参数进行排队。
简单地说,请阅读编译器输出,不要像我一样愚蠢:)您可能需要在同步器之后进行连接;或者在connect中使用Qt::QueuedConnection参数。我将您的代码复制到我的应用程序中,它工作正常。也许我没有正确地阅读这个问题?我不知道为什么它对你有效,因为我已经找到了罪魁祸首并在下面发布了它,所以我猜这是因为我在我的项目中启用了C++11。如果不是因为这个原因,那么我和你一样困惑。你提到如果你评论moveToThread并开始,它是有效的。这是错误的信息,然后呢?不,当我注释掉这两行时,它确实起作用了,但当时它不在一个单独的线程中,并且在与MainWindow对象相同的(主)线程上起作用。因此,我的猜测是,当您尝试将参数从线程中传递出去时,参数队列是适用的,并且在同一线程上工作时不需要参数队列,这很可能导致简单的本地方法调用,而没有任何奇特的队列。我不理解这与注册元类型有什么关系。它指出:对于排队连接,参数必须是Qt元对象系统已知的类型,因为Qt需要复制参数以将其存储在幕后事件中。
。当使用Qt::AutoConnection
时,它将在跨线程发送信号时使用排队连接<代码>如果信号是从与接收对象不同的线程发出的,则信号将排队,表现为Qt::QueuedConnection。否则,将直接调用插槽,其行为类似于Qt::DirectConnection。