1. 線程與界面組件需要注意的地方
- 在QThread線程中不能直接創建QWidget之類的界面組件.
- 因為在QT中,所有界面組件相關的操作都必須在主線程中(也就是GUI thread)
- 所以, QThread線程不能直接操作界面組件.
2.QThread線程如何操作界面組件-方法1
- 將多線程類對象封裝為GUI界面類的類成員
- 然后在子線程定義信號函數,通過信號槽機制,向界面組件emit發射信號,從而實現間接操作.
3.QThread線程如何操作界面組件-方法2
- 使用QApplication::postEvent()實現向界面發送事件,從而能夠封裝一個自定義類
4.使用Invokes()函數來調用界面組件的信號槽-方法3
一般使用該函數(用來調用對方的私有信號或槽):
該函數的連接方式默認使用的是Qt::AutoConnection
- 表示如果接收者和發送者在同一個線程,則自動使用Qt::DirectConnection類型。如果接收者和發送者不在一個線程,則自動使用Qt::QueuedConnection類型。
比如,當我們想調用一個obj下的compute(QString, int, double)槽函數時:
則只需要寫入:
QMetaObject::invokeMethod(obj, "compute", Q_ARG(QString, "sqrt"), Q_ARG(int, 42), Q_ARG(double, 9.7));
示例如下所示:
在Testtherd線程類里通過invokeMethod向父界面類的paintMsg槽函數發送信息
void Testtherd::run() {
int count=0; while(1) { QString str="請稍等,正在驗證用戶,登錄中"; for(int i =0;i<count;i++) str.append('.'); //循環添加小數點 count=(count+1)%7; QMetaObject::invokeMethod(this->parent(), "paintMsg", Q_ARG(QString, str)); msleep(500); } }
父界面類的paintMsg槽函數如下所示:
void loginwindow:: paintMsg(QString msg) { this->LineHint->setText(msg); }
運行效果如下: