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

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

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

这基本上是我线程的当前状态,没有什么特别之处,只是出于测试目的:

// 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。