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

时间:2014-01-02 00:20:17

标签: c++ multithreading qt

我只想将线程内的信号连接到主线程中的插槽来处理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的样子:

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

1 个答案:

答案 0 :(得分:1)

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

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

简单来说,阅读编译器输出并不像我一样愚蠢:)