成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

實現QT元類型和QT線程通信

移動開發
本文介紹的是實現QT元類型和QT線程通信,文中詳細介紹了如何實現,我們先來看內容。

實現QT元類型QT線程通信是本文將要介紹的內容,不多說廢話,先來看內容。今天調試QT線程通信的程序時,突然發現如下消息:

實現QT元類型和QT線程通信

其中PEOPLE只是我定義的枚舉類型即enum PEOPLE。然后在Qt的信號-槽函數的參數中使用了這個枚舉型,在發送信號時就出現了上述警告。上面警告的大概意思是信號隊列中無法使用PEOPLE類型,要使用qRegisterMetaType()注冊該類型后方可使用。

通常使用的connect,實際上最后一個參數使用的是Qt::AutoConnection類型:(友們,點擊之后,就會放大,不好意思,影響你視覺了)

實現QT元類型和QT線程通信

Qt支持6種連接方式,其中3中最主要:

Qt::DirectConnection(直連方式)

當信號發出后,相應的槽函數將立即被調用。emit語句后的代碼將在所有槽函數執行完畢后被執行。(信號與槽函數關系類似于函數調用,同步執行)

Qt::QueuedConnection(排隊方式)

當信號發出后,排隊到信號隊列中,需等到接收對象所屬線程的事件循環取得控制權時才取得該信號,調用相應的槽函數。emit語句后的代碼將在發出信號后立即被執行,無需等待槽函數執行完畢。(此時信號被塞到信號隊列里了,信號與槽函數關系類似于消息通信,異步執行)

Qt::AutoConnection(自動方式)

Qt的默認連接方式,如果信號的發出和接收這個信號的對象同屬一個線程,那個工作方式與直連方式相同;否則工作方式與排隊方式相同。

我的項目中的確跨線程使用了PEOPLE為參數類型的信號,因此使用的應當是排隊方式的信號-槽機制,出現“隊列中無法使用PEOPLE類型”的警告信息就可以理解了。放狗搜了一圈,有篇文章提供了個這樣的解決方案:

  1. connect(cm, SIGNAL(sendLog(QUuid, QByteArray, bool)),   
  2.             this,SLOT(sendRes(QUuid,QByteArray,bool)));  

改為:

  1. connect(cm, SIGNAL(sendLog(QUuid, QByteArray, bool)),   
  2.             this,SLOT(sendRes(QUuid,QByteArray,bool)));  

 

這樣做的確能使警告信息消失,因為Qt官方文檔寫了:

  1. With queued connections, the parameters must be of types that are known to Qt's meta-object system,   
  2. because Qt needs to copy the arguments to store them in an event behind the scenes. 

即使用排隊方式的信號-槽機制,Qt的元對象系統(meta-object system)必須知道信號傳遞的參數類型。這里手動改為直連方式,Qt的元對象系統就不必知道參數類型了,于是警告信息消失。但這樣做是不安全的,見Qt官方文檔:

  1. Be aware that using direct connections when the sender and receiver live in different threads is unsafe if   
  2. an event loop is running in the receiver's thread, for the same reason that calling any function on an obje  
  3. ct living in another thread is unsafe. 

因此,咱還是老老實實地用qRegisterMetaType()注冊類型吧

我寫的線程通訊方法是采用信號槽機制,通常情況下,信號和槽機制可以同步操作,這就意味著在發射信號的時候,使用直接函數即可以立刻調用連接到一個信號上的多個槽。然而,當連接位于不同線程中的對象時,這一機制就會變得不同步起來,可以通過剛才介紹的,修改QObject::connect()的第5個可選參數而改變。

connect的第五個參數Qt::QueuedConnection表示槽函數由接受信號的線程所執行,如果不加表示槽函數由發出信號的次線程執行。當傳遞信號的參數類型不是QT的元類型時要先注冊,關于QT的元類型可以參看QT文檔。

QMetaType這個類里面列舉了所有的元類型。

以枚舉PEOPLE為例,注冊時首先Q_DECLARE_METATYPE(PEOPLE);

然后,int id=qRegisterMetaType<PEOPLE>("PEOPLE");

加上這兩句就注冊成功了。

#p#

貼個示例的代碼,次線程不斷更改一個PEOPLE{boy,girl}的信息傳給GUI主線程,主線程在GUI界面上顯示。

  1. mythread.h  
  2.  
  3. view plaincopy to clipboardprint?  
  4. #ifndef MYTHREAD_H     
  5. #define MYTHREAD_H     
  6. #include <QThread>     
  7. enum PEOPLE{boy,girl};     
  8. class MyThread : public QThread     
  9. {     
  10. Q_OBJECT     
  11.     
  12. public:     
  13. MyThread();     
  14. ~MyThread();     
  15. protected:     
  16. void run();     
  17. signals:     
  18. void changeText(PEOPLE pe);     
  19. };     
  20. #endif // MYTHREAD_H    
  21. #ifndef MYTHREAD_H  
  22. #define MYTHREAD_H  
  23. #include <QThread> 
  24. enum PEOPLE{boy,girl};  
  25. class MyThread : public QThread  
  26. {  
  27. Q_OBJECT  
  28. public:  
  29. MyThread();  
  30. ~MyThread();  
  31. protected:  
  32. void run();  
  33. signals:  
  34. void changeText(PEOPLE pe);  
  35. };  
  36. #endif // MYTHREAD_H   
  37.  
  38. mainwindow.h  
  39. view plaincopy to clipboardprint?  
  40. #ifndef MAINWINDOW_H     
  41. #define MAINWINDOW_H     
  42. #include "mythread.h"     
  43. #include <QMainWindow>     
  44. namespace Ui {     
  45.     class MainWindow;     
  46. }     
  47.     
  48. class MainWindow : public QMainWindow {     
  49.     Q_OBJECT     
  50. public:     
  51.     MainWindow(QWidget *parent = 0);     
  52.     ~MainWindow();     
  53. private slots:     
  54. void labelSetText(PEOPLE qstr);     
  55. protected:     
  56.     void changeEvent(QEvent *e);     
  57. private:     
  58.     Ui::MainWindow *ui;     
  59. };     
  60. #endif // MAINWINDOW_H    
  61. #ifndef MAINWINDOW_H  
  62. #define MAINWINDOW_H  
  63. #include "mythread.h"  
  64. #include <QMainWindow> 
  65. namespace Ui {  
  66.     class MainWindow;  
  67. }  
  68. class MainWindow : public QMainWindow {  
  69.     Q_OBJECT  
  70. public:  
  71.     MainWindow(QWidget *parent = 0);  
  72.     ~MainWindow();  
  73. private slots:  
  74. void labelSetText(PEOPLE qstr);  
  75. protected:  
  76.     void changeEvent(QEvent *e);  
  77. private:  
  78.     Ui::MainWindow *ui;  
  79. };  
  80. #endif // MAINWINDOW_H   
  81.  
  82. mythread.cpp  
  83. view plaincopy to clipboardprint?  
  84. #include "mythread.h"     
  85. MyThread::MyThread()     
  86. : QThread()     
  87. {     
  88. }     
  89. MyThread::~MyThread()     
  90. {     
  91. }     
  92. void MyThread::run(){     
  93.  static int i=1;     
  94.  while(true)     
  95.  {     
  96.   if(i==1)emit changeText(boy);     
  97.   else emit changeText(girl);     
  98.   ii=i*(-1);     
  99.  QThread::sleep(1);     
  100.  }     
  101. }    
  102. #include "mythread.h"  
  103. MyThread::MyThread()  
  104. : QThread()  
  105. {  
  106. }  
  107. MyThread::~MyThread()  
  108. {  
  109. }  
  110. void MyThread::run(){  
  111.  static int i=1;  
  112.  while(true)  
  113.  {  
  114.   if(i==1)emit changeText(boy);  
  115.   else emit changeText(girl);  
  116.   ii=i*(-1);  
  117.  QThread::sleep(1);  
  118.  }  
  119. }  
  120.  
  121. mainwindow.cpp  
  122. view plaincopy to clipboardprint?  
  123. #include "mainwindow.h"     
  124. #include "ui_mainwindow.h"     
  125. #include "mythread.h"     
  126. MainWindow::MainWindow(QWidget *parent) :     
  127.     QMainWindow(parent),     
  128.     ui(new Ui::MainWindow)     
  129. {     
  130.     ui->setupUi(this);     
  131.     MyThread *mythread = new MyThread;     
  132.     int id=qRegisterMetaType<PEOPLE>("PEOPLE");     
  133.     connect(mythread,SIGNAL(changeText(PEOPLE)),this,SLOT(labelSetText(PEOPLE)),Qt::QueuedConnection);     
  134.     mythread->start();     
  135.     
  136. }     
  137. MainWindow::~MainWindow()     
  138. {     
  139.     delete ui;     
  140. }     
  141. void MainWindow::changeEvent(QEvent *e)     
  142. {     
  143.     QMainWindow::changeEvent(e);     
  144.     switch (e->type()) {     
  145.     case QEvent::LanguageChange:     
  146.         ui->retranslateUi(this);     
  147.         break;     
  148.     default:     
  149.         break;     
  150.     }     
  151. }     
  152. void MainWindow::labelSetText(PEOPLE qstr){     
  153. switch(qstr)     
  154. {     
  155. case boy:     
  156.     ui->label->setText("BOY");break;     
  157. case girl:     
  158.     ui->label->setText("GIRL");break;     
  159. }     
  160. }  

小結:實現QT元類型QT線程通信的內容到這就介紹完了,希望本文能幫你解決問題。

責任編輯:zhaolei 來源: 互聯網
相關推薦

2011-06-22 14:04:33

Qt 元類型 注冊

2011-06-13 17:46:07

Qt 串口通信

2011-06-23 13:38:27

QT 元對象 信號

2011-06-22 10:12:08

Qt 線程

2011-06-27 11:08:37

Qt 串口 通信

2011-06-30 09:46:01

QT 顯示視頻 linux

2011-06-14 09:46:11

Qt QThread 線程

2011-06-20 13:43:08

Qt Socket 線程

2011-06-22 17:09:50

QT 進程 通信

2011-06-22 15:50:45

QT 線程

2011-06-22 15:09:34

Qt 線程 sleep

2011-06-13 10:44:44

Qt Flash

2011-06-22 16:18:23

QT 多線程 QSocket

2011-06-22 16:50:09

Qt 進程 通信機制

2011-06-22 17:27:19

QT 進程通信

2011-06-22 15:24:50

Qt 線程

2011-06-13 10:03:19

Qt 多線程 編程

2011-07-01 13:03:32

QT 線程 串口

2011-06-30 11:23:29

Qt 線程

2011-06-29 16:34:11

Qt 子線程 線程
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日本精品视频一区二区 | 国产日韩欧美91 | 成人免费一区二区 | 超碰地址| 国产美女福利在线观看 | 久久久久久久久91 | 欧美激情精品久久久久 | 尤物在线精品视频 | 亚洲精品二区 | 色爱区综合 | 午夜免费| 精品国产欧美 | 中文字幕日本一区二区 | 欧美在线高清 | 国产乱码高清区二区三区在线 | 国产欧美一区二区三区日本久久久 | 欧美在线a | 亚洲九九| 色偷偷噜噜噜亚洲男人 | 免费看a | 偷派自拍 | 成人精品在线观看 | 久久久久久国产一区二区三区 | 激情a | 欧美aⅴ片| 欧美精品一区二区三区在线 | 一级看片免费视频 | www..com18午夜观看| 国产91在线观看 | 成年人在线观看视频 | 国产激情在线播放 | 国产精品免费一区二区三区四区 | 玖操| 亚洲色在线视频 | 91视频大全| 日韩成人免费视频 | 成人精品视频在线观看 | 男女免费在线观看视频 | 欧产日产国产精品国产 | 午夜久久久久久久久久一区二区 | 欧美精品1区 |