問題描述
Qt 文檔聲明信號和槽可以direct
、queued
和auto
.
Qt documentation states that signals and slots can be direct
, queued
and auto
.
它還指出,如果擁有插槽的對象生活"在與擁有信號的對象不同的線程中,則發出此類信號就像發布消息一樣 - 信號發射將立即返回,并且將在目標線程的事件循環中調用插槽方法.
It also stated that if object that owns slot 'lives' in a thread different from object that owns signal, emitting such signal will be like posting message - signal emit will return instantly and slot method will be called in target thread's event loop.
不幸的是,文檔沒有指明lives"代表什么,也沒有可用的示例.我嘗試了以下代碼:
Unfortunately, documentation do not specify that 'lives' stands for and no examples is available. I have tried the following code:
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()
永遠不會被調用 :(.我做錯了什么?
MySlot()
is never called :(. What I'm doing wrong?
推薦答案
你的代碼有不少問題:
- 就像 Evan 所說的那樣,缺少 emit 關鍵字
- 您所有的對象都存在于主線程中,只有 run 方法中的代碼存在于其他線程中,這意味著將在主線程中調用 MySlot 插槽,我不確定這是否是您想要的
- 你的槽永遠不會被調用,因為主事件循環永遠不會被啟動:你對 wait() 的兩次調用只會在很長時間后超時(你可能會在這之前殺死你的應用程序),我不也不要認為那是您想要的,無論如何它們在您的代碼中確實沒有用處.
這段代碼很可能會起作用(雖然我還沒有測試過),而且我認為它可以完成您想要它做的事情:
This code would most likely work (though I have not tested it) and I think it does what you want it to do :
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).
Now MyObject will live in thread2 (thanks to moveToThread).
MySignal 應該從 thread1 發送(我不確定那個,它可能是從主線程發送的,這并不重要).
MySignal should be sent from thread1 (thought I'm not sure on that one, it might be sent from main thread, it doesn't really matter).
線程 1 中不需要事件循環,因為發出信號不需要事件循環.線程 2 中需要一個事件循環(由 exec() 啟動)來接收信號.
No event loop is needed in thread1 since emitting a signal doesn't need an event loop. An event loop is needed in thread2 (lanched by exec()) to receive the signal.
MySlot 將在線程 2 中調用.
MySlot will be called in thread2.
這篇關于如何在Qt中發出跨線程信號?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!