Re: [問題] Qt thread

看板C_and_CPP作者 (aa)時間14年前 (2011/06/21 22:43), 編輯推噓1(100)
留言1則, 1人參與, 最新討論串4/6 (看更多)
看了這篇還是不太懂實際上要怎麼做 原始例子,沒有使用thread需等一個動作執行完才能執行下一個 兩個button各會print 1到10000 希望可以按下A後馬上按B,然後看見A和B的訊息交錯出現 http://codepad.org/ud00zmZu http://codepad.org/aDutgyMF http://codepad.org/VqfeRUi1 目前的想法 http://codepad.org/Q1iIhufB (同下面等號後的文字) 希望可以有人給建議,對Qt還沒有很熟 有時候程式有錯誤時會搞不清楚到底是這樣不可行 還是只是自己沒寫好 所以想先請教一下整體的概念 謝謝 ================ 如果有一個UI上有很多button各自要做的事情都是獨立的 btnA(doA), btnB(doB) 那建立一個mainwindow的class後 再建立一個Thread的class, btnThread 還是每件事情都要建立一個, btnAThread, btnBThread? 如果是只建立一個class, btnThread的話 又如L大所建議不要繼承QThread 目前的想法如下,但覺得怪怪的 在btnThread中建立兩個slot doA和doB 以及兩個signal signalA和signalB void btnThread::doA() { QThread * thread = new QThread; this->moveToThread( thread ); this->( thread, SIGNAL( started() ), SLOT( RealdoA() ) ); thread->connect( this, SIGNAL( done() ), SLOT( quit() ) ); thread->start(); } void btnThread::RealdoA() { for(int i=0;i<10000;i++) { QString value; value.sprintf("A%d",i); signalA(value); } } 在mainwindow中 btnThread *threadA; btnThread *threadB; btnA = new QPushButton(tr("A")); connect(btnA, SIGNAL(clicked()), threadA, SLOT(doA())); connect(threadA, SIGNAL(signalA(QString)), this, SLOT(update(QString)); btnB = new QPushButton(tr("B")); connect(btnB, SIGNAL(clicked()), threadB, SLOT(doB)); connect(threadA, SIGNAL(signalA(QString)), this, SLOT(update(QString)); http://codepad.org/ud00zmZu http://codepad.org/aDutgyMF http://codepad.org/VqfeRUi1 http://codepad.org/Q1iIhufB ※ 引述《legnaleurc (CA)》之銘言: : ※ 引述《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: 1.169.133.96

06/22 00:45, , 1F
如果是 task 導向的 thread 可用 QRunnable
06/22 00:45, 1F
文章代碼(AID): #1E0AuHrZ (C_and_CPP)
討論串 (同標題文章)
本文引述了以下文章的的內容:
以下文章回應了本文
完整討論串 (本文為第 4 之 6 篇):
文章代碼(AID): #1E0AuHrZ (C_and_CPP)