Qt文档说明信号和插槽可以是direct
、queued
和auto
。
它还指出,如果拥有slot的对象‘生活’在与拥有信号的对象不同的线程中,发出这样的信号将类似于发布消息- signal emit将立即返回,slot方法将在目标线程的事件循环中被调用。
不幸的是,文档并没有指定'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()
:(.我哪里做错了?
发布于 2009-03-12 13:49:40
你的代码有很多问题:
正如Evan所说,emit关键字缺少
()的两次调用
这段代码很可能会工作(尽管我还没有测试过它),而且我认为它能做你想让它做的事情:
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()调用)中需要一个事件循环来接收信号。
将在thread2中调用MySlot。
发布于 2011-12-03 01:24:34
不要为Qt 4.4+创建QThread子类
虽然Aiua的答案是好的,但我想指出QThread和Qt4.6或4.7的一些问题。
本文对此进行了总结:http://blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/
缺乏关于Qt部分的文档
不幸的是,这个问题源于缺少对文档的更新。在Qt4.4之前,QThread没有默认的run()实现,这意味着您必须继承QThread才能使用它。
如果你使用的是Qt4.6或4.7,那么你几乎肯定不应该继承QThread的子类。
使用moveToThread
正如Aiua指出的那样,让插槽在工作线程中执行的关键是使用moveToThread方法。
发布于 2018-12-22 11:27:50
您应该发出信号来启动线程函数,如下所示
emit operateCut(examId,examName_examTemplate[examName].studentIdRec,examName_examTemplate[examName].choiceRecA,examName_examTemplate[examName].choiceRecB,examName_examTemplate[examName].objectRecA,examName_examTemplate[examName].objectRecB);
您可以在此信号中添加多个参数
https://stackoverflow.com/questions/638251
复制相似问题