c++ - Qt moveToThread,带参数的信号/槽

标签 c++ qt

我尝试使用来自 https://wiki.qt.io/QThreads_general_usage 的方法 与 moveToThread。一切安好。但是,如果我尝试将参数添加到完成的信号中,则会出现以下问题:

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 的预期行为吗?

最佳答案

问题是元数据信息。

当你做 default connection在信号和槽之间,当信号从不同的线程发出而不是接收者被分配到时,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 日志,我确定它会提示您正确的错误消息。

关于c++ - Qt moveToThread,带参数的信号/槽,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51822393/

相关文章:

c++ - DirectX:在设备之前获取InfoQueue

c# - 在 C++ 中将 int 转换为 little-endian 格式的字节以用于 Azure 中的 blobId

c++ - 使用 cxxtest 框架和 valgrind 测试 qt 对象

c++ - QPixmap 不适用于存储在变量中的图像路径

c++ - VS2017 和在 Win7/XP 上缺少 "api-ms-win-core-rtlsupport-l1-2-0.dll"

c++ - 变量不能明确

c++ - 检测将 HRESULT 作为 bool 值使用

c++ - 在 C++ 和 Eclipse 上包含字符串类

c++ - 在 C++ 中获取应用程序窗口的大小

qt - 为什么 QTreeWidget 的顶部有一个 1?