GUI(主)线程与子线程之间的通信

转自:http://blog.csdn.net/small_qch/article/details/6681907


在主线程上,可以控制子线程启动,停止,清零

如果子线程启动的话,每一秒钟会向主线程发送一个数字,让主线程更新界面上的数字。


程序截图:



上代码:

  1. #include <QtGui>    
  2. #include <QtCore>   
  3. #include <windows.h>  
  4.   
  5. class Thread : public QThread    
  6. {    
  7.     Q_OBJECT    
  8. private:    
  9.     int number;    
  10. protected:    
  11.     void run();    
  12. public:    
  13.     Thread(QObject *parent=0);    
  14.     ~Thread();    
  15. signals:    
  16.     void UpdateSignal(int num);    
  17.     public slots:    
  18.         void ResetSlot();    
  19. };    
  20.   
  21. class Widget : public QWidget    
  22. {    
  23.     Q_OBJECT    
  24. private:    
  25.     QLabel *label;    
  26.     QPushButton *startButton;    
  27.     QPushButton *stopButton;    
  28.     QPushButton *resetButton;    
  29.     Thread *myThread;    
  30.     int number;    
  31. public:    
  32.     Widget(QWidget *parent = 0);    
  33.     ~Widget();    
  34. signals:    
  35.     void ResetSignal();    
  36.     public slots:    
  37.         void ClearSlot();    
  38.         void StartSlot();    
  39.         void StopSlot();    
  40.         void UpdateSlot(int num);    
  41. };    
  42.   
  43. Thread::Thread(QObject *parent)    
  44. {    
  45.     number = 0;    
  46. }    
  47.   
  48. Thread::~Thread()    
  49. {    
  50.   
  51. }    
  52.   
  53. void Thread::run()    
  54. {    
  55.     while(1)    
  56.     {    
  57.         //开启一个死循环,让number每秒自增1,并通过发送UpdateSignal信号通知主界面更新  
  58.         emit UpdateSignal(number);    
  59.         number++;    
  60.         sleep(1);    
  61.     }    
  62. }    
  63.   
  64. void Thread::ResetSlot()    
  65. {    
  66.     number = 0;    
  67.     emit UpdateSignal(number);    
  68. }    
  69.   
  70. Widget::Widget(QWidget *parent)    
  71. {    
  72.     //设置界面布局  
  73.     startButton = new QPushButton("start");    
  74.     stopButton = new QPushButton("stop");    
  75.     resetButton = new QPushButton("reset");    
  76.     label = new QLabel("empty");    
  77.     myThread = new Thread;    
  78.     QVBoxLayout *layout = new QVBoxLayout;    
  79.     layout->addWidget(label);    
  80.     layout->addWidget(startButton);    
  81.     layout->addWidget(stopButton);    
  82.     layout->addWidget(resetButton);    
  83.     setLayout(layout);    
  84.   
  85.     //连接各自信号糟  
  86.     connect(stopButton, SIGNAL(clicked()),     
  87.         this, SLOT(StopSlot()));    
  88.     connect(startButton, SIGNAL(clicked()),    
  89.         this, SLOT(StartSlot()));    
  90.     connect(resetButton, SIGNAL(clicked()),    
  91.         this, SLOT(ClearSlot()));    
  92.     connect(myThread, SIGNAL(UpdateSignal(int)),     
  93.         this, SLOT(UpdateSlot(int)));    
  94.     connect(this, SIGNAL(ResetSignal()),    
  95.         myThread, SLOT(ResetSlot()));    
  96.   
  97.   
  98.     setWindowTitle("Thread Test");    
  99.     resize(200, 200);    
  100.     myThread->start();    
  101.   
  102. }    
  103.   
  104. Widget::~Widget()    
  105. {    
  106.   
  107. }    
  108.   
  109. void Widget::StartSlot()    
  110. {    
  111.     myThread->start();    
  112. }    
  113.   
  114. void Widget::StopSlot()    
  115. {    
  116.     myThread->terminate();    
  117. }    
  118.   
  119. void Widget::UpdateSlot(int num)    
  120. {    
  121.     label->setText(QString::number(num));    
  122. }    
  123.   
  124. void Widget::ClearSlot()    
  125. {    
  126.     emit ResetSignal();    
  127. }    
  128.   
  129. #include "main.moc"  
  130.   
  131. int main(int argc, char **argv)    
  132. {    
  133.     QApplication app(argc, argv);    
  134.     Widget *widget = new Widget;    
  135.     widget->show();    
  136.     return app.exec();    
  137. }   
其他相关文章:http://blog.csdn.net/dongfangyu/article/details/5972764
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GUI线程和Worker线程是常见的多线程编程模型,用于实现图形用户界面(GUI)应用程序的并发处理。 1. GUI线程(也称为线程):GUI线程负责处理用户界面的绘制、响应用户输入等任务。在大多数GUI框架中,GUI线程也是事件循环线程,负责监听和分发用户事件(如鼠标点击、键盘输入)并对其作出相应的响应。在这种模型下,GUI线程通常是单线程的,意味着在GUI线程中执行的任何耗时操作都会导致界面冻结,造成用户体验下降。 2. Worker线程:Worker线程用于执行耗时的任务,以避免在GUI线程中阻塞。这些任务可以是计算密集型的操作,如图像处理、数据分析等,也可以是I/O密集型的操作,如文件读写、网络请求等。通过将这些任务放在Worker线程中执行,可以保持GUI线程的响应性,使用户能够继续与界面进行交互。 在实际开发中,通常采用以下方式来实现GUI线程和Worker线程的协同工作: 1. 任务分发:GUI线程接收用户事件,并将耗时任务委托给Worker线程处理。这可以通过消息队列、事件驱动等机制来实现,GUI线程将任务放入队列中,Worker线程从队列中取出任务并执行。 2. 线程间通信GUI线程和Worker线之间需要进行数据交换和同步。常见的线程间通信方式包括使用线程安全的队列、事件、互斥锁、条件变量等机制。 3. 界面更新:在Worker线程执行完耗时任务后,需要将结果返回给GUI线程,并更新界面显示。通常可以通过回调函数、信号槽机制等方式来实现。 需要注意的是,在多线程编程中,要注意线程安全性和资源管理,避免竞态条件、死锁等问题的发生。此外,对于一些特殊的操作,如对GUI组件的修改,可能需要在GUI线程中执行,以避免跨线程访问的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值