【发布时间】:2019-08-30 09:45:07
【问题描述】:
我有一个 Qt 应用程序。我的一个班级ViewSimulation 有一个静态方法loggingHandler,它调用(发出)一个类信号logging。方法loggingHandler 将作为函数指针传递给c 文件publisher.c。 publisher.c 在单独的线程中调用他的函数指针 (*logger)。
在调试时,我看到publisher.c 调用ViewSimulation::loggingHandler 并发出信号logging,但连接的插槽没有反应。但是如果在主线程中调用/发出logging,&ViewGooseList::logging) 的插槽会做出反应。
为什么插槽没有通过从publisher.c 中的其他c-thread“调用”来做出反应?
ViewSimulation.cpp/h
class ViewSimulation : public QGroupBox
{
...
signals:
void logging(int id, uint64_t timestamp);
private:
static void loggingHandler(int id, uint64_t timestamp);
ViewSimulation* ViewSimulation::m_current;
...
void ViewSimulation::loggingHandler(int id, uint64_t timestamp)
{
emit ViewSimulation::m_current->logging(id, timestamp);
}
...
connect(m_gooseSimulation, &ViewSimulation::logging, m_gooseList, &ViewGooseList::logging);
setLogging(loggingHandler);
publisher.c/h
/*Header*/
void setLogging(void (*logging)(int, uint64_t));
static void (*logger)(int gooseId, uint64_t timestamp);
/*C-File*/
void setLogging(void (*logging)(int, uint64_t))
{
logger = logging;
}
...
/*This methode will be called from main-thread **AND** from second thread */
logger(gooseMessage->id, gooseMessage->lastTimeStamp);
...
【问题讨论】:
-
如果显式创建队列连接会发生什么:
connect(m_gooseSimulation, &ViewSimulation::logging, m_gooseList, &ViewGooseList::logging, Qt::QueuedConnection); -
@NikosC。现在它似乎工作了。谢谢。
-
@NikosC。奇怪的行为导致默认连接类型是 AutoConnection,它确定对象是否在其他线程中,如果是,则自动使用 QueuedConnection。
-
@someoneinthebox 这很奇怪。但我自己也遇到过这个问题几次。我不知道为什么
Qt::AutoConnection在某些连接上失败:-/ 也许当发出信号的对象被移动到 QThread 但emit代表该对象从另一个线程发生时,它会失败.或者,该对象可能没有移动到 QThread,但它是从线程中使用的。那我猜它也会失败。
标签: c++ c multithreading qt