簡體   English   中英

Qt moveToThread,帶有參數的信號/插槽

[英]Qt moveToThread, signals/slots with arguments

我嘗試通過moveToThread使用https://wiki.qt.io/QThreads_general_usage中的方法。 一切順利。 但是,如果我嘗試將參數添加到完成的信號中,則會出現以下問題:

class Worker : public QObject {
Q_OBJECT
public:
   Worker();
   ~Worker();
public slots:
   void process();
signals:
   void finished(const std::string& value);
};

void Worker::process() { // Process. Start processing data.
    // allocate resources using new here
    qDebug("Hello World!");
    std::string s = someFunctionReturningString(); 
    emit finished(s);
}

主要類別是:

class Main: public QObject {
Q_OBJECT
public:
    void startProgram();
public slots:
   void slotFinished(const std::string& s);
};

void Main::startProgram() {
   QThread* thread = new QThread;
   Worker* worker = new Worker();
   worker->moveToThread(thread);
   connect(thread, &QThread::started, worker, &Worker::process);
   connect(worker, &Worker::finished, thread, &QThread::quit);
   connect(worker, &Worker::finished, worker, &Worker::deleteLater);
   connect(worker, &Worker::finished, this,   &Main::slotFinished);
   connect(thread, &QThread::finished, thread, &QThread::deleteLater);
   thread->start();
}

void Main::slotFinished(const std::string& value) {
    qDebug() << "result " << value.c_str();
}

如果我將完成的信號連接到某個插槽(slotFinished),則不會接到該插槽的電話。

是信號/插槽/ moveToThread的預期行為嗎?

問題是元數據信息。

當您在信號和插槽之間建立默認連接 ,並且當信號從與接收者分配給的線程不同的線程發出時,Qt發揮了魔力,並包裝了信號的參數(創建副本)並將它們放在目標線程的事件循環中。

然后,當目標暫存區執行Qt事件循環的邏輯時,將解包值,並使用復制的值調用相應的插槽。

為了能夠進行此復制,Qt必須對這種類型有一些最低的了解。 因此,當您使用Qt類型時,它可以立即使用,但是如果您使用的是外部類型(如std::string ,則必須首先執行類型注冊。

所以基本上您的代碼缺少這樣的事情:

// to be declared somewhere
Q_DECLARE_METATYPE(std::string);

// to be invoked at the beginning of program
qRegisterMetaType<std::string>();

如果沒有類型注冊,Qt將不知道如何進行復制,並且會在日志中提供警告。 檢查Qt日志,我確定它會提示您正確的錯誤消息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM