看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《PeterKiller (Peter)》之銘言: : 開發平台(Platform): (Ex: VC++, GCC, Linux, ...) Ubuntu 10.10 gcc : 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) Qt : 問題(Question): 各位版上的高手好 最近在看學習筆記學Qt : 學到Qthread時 發現他給的範例不能照常執行 來爬文發現在Qthread中 : 不能有QWidget的物件,需要用signal和slut實做。 : 現在遇到的困難是 我寫了一個遊戲開了兩條Qthread,其中第一條是遊戲邏輯, : 第二條則是讓他一直刷新遊戲畫面,所以我在第二條Qthread中的run只是一直發signal : 讓我的main thread(GUI thread)去執行update()這個函式..但是我編譯完執行後就發現 : 他整個程式都block住沒辦法動了,想請問各為有什麼解決的辦法? : code 在此: : main : http://codepad.org/mwJ3FXRn : QWidget object :http://codepad.org/Ellr2zk0 : http://codepad.org/FNvMKyL9 : graph thread : http://codepad.org/TR3aeDvK : 謝謝 強力推薦這篇文章: http://developer.qt.nokia.com/wiki/ThreadsEventsQObjects (有簡體中文版,但個人認為翻得不好) 這篇文章還指出 Qt 官方文件有部分是錯誤的 簡單的說,QThread 不是這麼用的(但是很多舊式的 code 都教你這麼用) QThread 在 run() 裡的動作的確是在另一條 thread 上執行 但除了 run() 以外的部分,都是在原本的 thread (a.k.a. main thread) 上 所以你在 signal/slot connection 的時候,用的是 direct connection 因為兩個實體都在同一個 thread 裡 結果就造成 event loop blocking 若是兩個實體在不同 threads 上,signal/slot connection 才會 用 queued connection QThread 在定位上其實是一個最低階的,用來管理 thread 的類別 這是為什麼 Qt 4.4 之後把它改為 concrete class 的原因 真正設計為用來繼承的是 QRunnable, 配合 QThreadPool 使用 QtConcurrent 則是最高階的 thread API 回到原題 你的 Graph_thread 不需要繼承 QThread,只要繼承 QObject 就好 然後建立一個 QThread 實體,使用 QObject::moveToThread() 那麼 connection 就會跨越 threads 假設你要跑在 thread 裡的函式叫 Graph_thread::doWork() 結束時會發出 signal 叫 Graph_thread::done() QThread * thread = new QThread; graph->moveToThread( thread ); // 使用新建的 thread graph->connect( thread, SIGNAL( started() ), SLOT( doWork() ) ); thread->connect( graph, SIGNAL( done() ), SLOT( quit() ) ); thread->start(); PS: thread 的清理可使用 QObject::deleteLater() -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 123.205.248.119 ※ 編輯: legnaleurc 來自: 123.205.248.119 (04/06 02:19)
uranusjr:推, 原來還有 started 跟 done 可以用, 我都傻傻的還是 04/06 02:22
uranusjr:subclass QThread 然後在 run() 裡面呼叫 doWork... 04/06 02:23
legnaleurc:這個作法的麻煩點是 QThread 什麼時候可以回收 04/06 02:24
legnaleurc:以原PO 的狀況,應該是不需要回收,因為它不會結束 04/06 02:25
PeterKiller:感謝 我馬上改試試看~ 04/06 02:33
PeterKiller:耶 可以順利執行了 太感謝了再推一次! 04/07 01:52
StrangeJ:推一個 09/24 10:18