問題描述
下面是我的 qthread 實現代碼.我正在嘗試從衛星獲取 GPS 數據.即使程序退出 gpsSearch()
槽函數,QThread 也不會產生finished() 信號.每當單擊按鈕時都會調用函數 locateMe()
.第一次當線程未啟動并單擊按鈕時,它會為 isRunning()
函數打印真值,并為 isFinished()
函數打印假值.我不得不調用 QTherad 的 quit()
函數來手動停止線程.之后,它轉到 gnssProvider
類中連接的 threadQuit()
函數.但即使在那之后,如果我點擊按鈕,它會在 locateMe()
函數中為 isRunning
打印真值,為 isFinished()
打印假值.
Below is the code for my qthread implementation. I am trying to get gps data from satellite. QThread doesn't produce the finished() signal even when the programs exits gpsSearch()
slot function. The function locateMe()
is called whenever a button is clicked. The first time when the thread isnt started and the button is clicked it prints true value for isRunning()
function and prints false value for isFinished()
function. I had to call the quit()
function of the QTherad to manually stop the thread. After that it goes to the connected threadQuit()
function in the gnssProvider
class. But even after that if I click the button it prints true value for isRunning
and false for isFinished()
in the locateMe()
function.
GPSInfo::GPSInfo()
{
hybridGPSFound = satelliteGPSFound = networkGPSFound = false;
qDebug()<<"Thread Creating";
gnssThread = new QThread;
gnssProvider = new LocationFetcher(this,GEOLOCATION_PROVIDER_GNSS,1);
gnssProvider->moveToThread(gnssThread);
connect(gnssThread, SIGNAL(started()), gnssProvider, SLOT(gpsSearch()));
connect(gnssThread, SIGNAL(finished()), gnssProvider, SLOT(threadQuit()));
}
void LocationFetcher::gpsSearch()
{
if (BPS_SUCCESS != geolocation_request_events(0))
{
fprintf(stderr, "Error requesting geolocation events: %s", strerror(errno));
return;
}
geolocation_set_provider(GPS_Search_Provider);
geolocation_set_period(GPS_Search_Period);
while (!stopThread)
{
bps_event_t *event = NULL;
bps_get_event(&event, -1);
if (event)
{
if (bps_event_get_domain(event) == geolocation_get_domain() && bps_event_get_code(event) == GEOLOCATION_INFO)
{
handle_geolocation_response(event);
break;
}
}
}
geolocation_stop_events(0);
this->quit();
}
void GPSInfo::LocateMe()
{
qDebug()<<"Thread Running: "<<gnssThread->isFinished();
qDebug()<<"Thread Running: "<<gnssThread->isRunning();
gnssThread->start();
hybridThread->start();
networkThread->start();
}
推薦答案
QThread 生命周期的工作方式是這樣的:
The way the QThread lifecycle works is like this:
- 你調用
QThread::start()
. - 此時,
isRunning()
應該開始返回 true. - 線程內部開始.它們發出
started()
信號. - 線程內部調用
run()
. - 除非你在子類中重寫它,
run()
調用exec()
. exec()
進入一個事件循環并保持在那里直到quit()
或exit()
被調用.exec()
和run()
返回內部.- 此時,
isFinished()
應該開始返回 true 和isRunning()
false. - 內部發出
finished()
信號. - 內部人員做了一些最后的清理工作.
- 線程真正終止.
- You call
QThread::start()
. - At this point,
isRunning()
should start returning true. - The thread internals start. They emit the
started()
signal. - The thread internals call
run()
. - Unless you override this in a subclass,
run()
callsexec()
. exec()
enters an event loop and stays there untilquit()
orexit()
is called.exec()
andrun()
return to the internals.- At this point,
isFinished()
should start returning true andisRunning()
false. - The internals emit the
finished()
signal. - The internals do some final cleanups.
- The thread terminates for real.
所以你需要在你的位置獲取器完成后調用 quit()
- 但是 this->quit()
沒有調用 quit()
在線程上!這可能就是它什么都不做的原因.
So you need to call quit()
after your location fetcher is done - but this->quit()
isn't calling quit()
on the thread! This is probably why it's not doing anything.
你的代碼看起來有點像這篇文章之后的模式:
Your code looks a bit like it was patterned after this article:
http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
注意她如何給她的工人一個 finished()
信號(與 QThread::finished
不同)并將其連接到 QThread::quit()
槽.
Note how she gives her worker a finished()
signal (not the same as QThread::finished
) and connects it to the QThread::quit()
slot.
這篇關于QThread 發出finished() 信號但isRunning() 返回true 并且isFinished() 返回false的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!