Qt 文档指出信号和槽可以direct
, queued
and auto
.
它还指出,如果拥有插槽的对象“生活”在与拥有信号的对象不同的线程中,则发出此类信号将像发布消息一样 - 信号发出将立即返回,并且将在目标线程的事件循环中调用插槽方法。
不幸的是,文档没有指定“lives”代表什么,也没有可用的示例。我尝试过以下代码:
main.h:
class CThread1 : public QThread
{
Q_OBJECT
public:
void run( void )
{
msleep( 200 );
std::cout << "thread 1 started" << std::endl;
MySignal();
exec();
}
signals:
void MySignal( void );
};
class CThread2 : public QThread
{
Q_OBJECT
public:
void run( void )
{
std::cout << "thread 2 started" << std::endl;
exec();
}
public slots:
void MySlot( void )
{
std::cout << "slot called" << std::endl;
}
};
main.cpp:
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
CThread1 oThread1;
CThread2 oThread2;
QObject::connect( & oThread1, SIGNAL( MySignal() ),
& oThread2, SLOT( MySlot() ) );
oThread1.start();
oThread2.start();
oThread1.wait();
oThread2.wait();
return a.exec();
}
输出是:
thread 2 started
thread 1 started
MySlot()
从未被调用:(。我做错了什么?
您的代码存在很多问题:
- 就像 Evan 所说的,emit 关键字丢失了
- 您的所有对象都位于主线程中,只有 run 方法中的代码位于其他线程中,这意味着 MySlot 插槽将在主线程中调用,我不确定这是否是您想要的
- 你的槽永远不会被调用,因为主事件循环永远不会启动:你对 wait() 的两次调用只会在很长一段时间后超时(并且你可能会在发生这种情况之前杀死你的应用程序),我不认为这也是你想要的,无论如何它们在你的代码中确实没有用。
这段代码很可能会工作(尽管我还没有测试过),并且我认为它可以实现您想要的功能:
class MyObject : public QObject
{
Q_OBJECT
public slots:
void MySlot( void )
{
std::cout << "slot called" << std::endl;
}
};
class CThread1 : public QThread
{
Q_OBJECT
public:
void run( void )
{
std::cout << "thread 1 started" << std::endl;
int i = 0;
while(1)
{
msleep( 200 );
i++;
if(i==1000)
emit MySignal();
}
}
signals:
void MySignal( void );
};
class CThread2 : public QThread
{
Q_OBJECT
public:
void run( void )
{
std::cout << "thread 2 started" << std::endl;
exec();
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
CThread1 oThread1;
CThread2 oThread2;
MyObject myObject;
QObject::connect( & oThread1, SIGNAL( MySignal() ),
& myObject, SLOT( MySlot() ) );
oThread2.start();
myObject.moveToThread(&oThread2)
oThread1.start();
return a.exec();
}
现在 MyObject 将存在于 thread2 中(感谢 moveToThread)。
MySignal 应该从 thread1 发送(我想我不确定这一点,它可能是从主线程发送的,这并不重要)。
thread1 中不需要事件循环,因为发出信号不需要事件循环。 thread2 中需要一个事件循环(由 exec() 启动)来接收信号。
MySlot 将在 thread2 中被调用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)