Re: [問題] Qt thread
看了這篇還是不太懂實際上要怎麼做
原始例子,沒有使用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
06/22 00:45, 1F
討論串 (同標題文章)