Qt在多线程中使用信号槽的示例

更新时间:2023-06-14 04:03:08 阅读: 评论:0

Qt在多线程中使⽤信号槽的⽰例
  之前对线程理解得不深⼊,所以对Qt的线程机制没有搞清楚,今天写⼀篇⽂章总结⼀下,如有错误,欢迎指出。
⾸先需要理解线程是什么,线程在代码中的表现其实就是⼀个函数,只不过这个函数和主线程的函数同时运⾏,写C语⾔的都知道,⼀般代码是从main()函数开始运⾏的,每个线程都有⼀个⼊⼝函数,main()函数可以看做是主线程的⼊⼝函数,从main函数开始执⾏,主线程就开始了,写过⼀点代码的都知道,程序是从main()函数开始⼀条⼀条地往下执⾏的,但是有的时候我们需要同时执⾏A,B两个函数。初学代码时,都是先调⽤A函数,再调⽤B函数,这时是A函数执⾏完毕后再执⾏B函数,没有达到我们想要同时执⾏的⽬的。这时如果把A 函数放⼊另⼀个线程中执⾏,那么不需要等到A函数执⾏完毕,B函数就可以开始执⾏。C++11中已经有了多线程库,简单⽰例如下
std::thread t(A);
B();
你可以随便写两个函数,函数名为A,B。函数内容可以写成输出10000次A(B函数可以输出10000次B,输出次数少了可能会观察不到),你可能会发现A和B会交替出现,这就是A和B在同时执⾏的证明。多
线程在图形界⾯程序中⼏乎是必须的,图形界⾯程序的主线程⼀般是界⾯线程,⽤于响应⽤户的操作,后台线程⽤于执⾏计算,通信等操作,如果不使⽤多线程,图形界⾯会因为等待计算数据(当然我说的是⼤量数据,少量数据你可能会感受不到)⽽卡住不响应⽤户的操作。讲到这⾥你也许对线程有了⼀个基本的印象。
Qt使⽤QThread类有两种⽅式,这个⽹上可以找到很多资料。
第⼀种:继承QThread类,⾃⼰写⼀个类(假设为MyThread),重写QThread的run()函数,新线程就会运⾏run()⾥⾯的代码,但是要注意的是只有run()函数⾥⾯的代码在新线程⾥运⾏,所以你⾃⼰的MyThread类⾥⾯的槽函数虽然和主线程的信号绑定了,但是只要没有放在run()⾥⾯运⾏,还是运⾏在主线程中的。
第⼆种:使⽤moveToThread(),我下⾯的⽰例代码就是使⽤的moveToThread()⽅法。QThrad中默认的run()函数启⽤了事件循环(exec()),所以你移动到线程中的那个对象的所有槽函数均在新线程中执⾏,不会阻塞主线程。看完⽰例就明⽩了。新建⼀个QApplication ⼯程,把mainwindow.h改成下⾯的代码
// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QApplication>
#include <QObject>
#include <QEvent>
#include <thread>
#include <iostream>
#include <QThread>
#include <QPushButton>
#include <QVBoxLayout>
#include <QMainWindow>
// network thread
class NetworkThread:public QObject感恩教育黑板报
{
Q_OBJECT
public:
NetworkThread()
{
// do some initial works;
}
signals:
void datacoming(int a);
private:
void memberFun();
public slots:
void testSlot();
void sleepSlot();
};
文明的重要性// network thread class
// GUI class,run in main thread
class MyWidget:public QMainWindow
{
Q_OBJECT
public:
QPushButton *firstButton,*condButton,*thirdButton;
QVBoxLayout *layout;
QWidget *p;
public:
explicit MyWidget(QWidget *parent);
~MyWidget();
signals:
void signalTestStart(int a=0);
void startNetworkSleep();
public slots:
void condButtonClicked();
};
// GUI class
// csApplication class
class csApplication:public QApplication
{
Q_OBJECT
public:
csApplication(int argc,char *argv[]);
MyWidget *mywindow;
NetworkThread *netthd;
QThread *t;
~
csApplication();
};
// csApplication class
#endif// MAINWINDOW_H
把main.cpp改成下⾯的代码,并删去mainwindow.cpp // main.cpp
#include "mainwindow.h"
// network thread
cur
void NetworkThread::testSlot()
{
{
std::cout<<"\nin testSlot()\n thread id:"<<std::this_thread::get_id()<<std::endl;
memberFun();
}
void NetworkThread::memberFun()
{
std::cout<<"\nin NetworkThread::memberFun()\nthread id:"<<std::this_thread::get_id()<<"\n"<<std::endl;
}
void NetworkThread::sleepSlot()
{
std::cout<<"in NetworkThread::sleepSlot()\n thread id:"<<std::this_thread::get_id()<<"\nthen sleep 5 conds\n";    QThread::sleep(5);
std::cout<<"sleepSlot() weak up\n"<<std::endl;
}
// network thread class
// GUI class,run in main thread
MyWidget::MyWidget(QWidget *parent=0)
眼睛构造图{
firstButton = new QPushButton(tr("first"));
condButton = new QPushButton(tr("cond"));
thirdButton = new QPushButton(tr("third"));
layout = new QVBoxLayout;
layout->addWidget(firstButton);
layout->addWidget(condButton);
layout->addWidget(thirdButton);
p=new QWidget;
正断层p->tLayout(layout);
tCentralWidget(p);
}
MyWidget::~MyWidget()
{
delete firstButton;
delete condButton;干贝排骨汤
delete thirdButton;
delete p;
拳击英文
delete layout;
}
void MyWidget::condButtonClicked()
{
emit startNetworkSleep();
std::cout<<"in MyWidget::condButtonClicked()\n thread id: "<<std::this_thread::get_id()<<"\n"<<std::endl;
}
// GUI class
// csApplication class
csApplication::csApplication(int argc, char *argv[]):QApplication(argc,argv)
{
std::cout<<"\nin csApplication()\nthread id:"<<std::this_thread::get_id()<<"\n"<<std::endl;
mywindow = new MyWidget();
netthd = new NetworkThread();
t = new QThread();
connect(mywindow->firstButton,SIGNAL(clicked()),netthd,SLOT(testSlot()),Qt::QueuedConnection);    connect(mywindow->condButton,SIGNAL(clicked()),mywindow,SLOT(condButtonClicked()));
connect(mywindow,SIGNAL(startNetworkSleep()),netthd,SLOT(sleepSlot()),Qt::QueuedConnection);
netthd->moveToThread(t);
t->start();
mywindow->show();
}
csApplication::~csApplication()
{
delete mywindow;
delete netthd;
delete t;
综合布线
}
// csApplication class
int main(int argc, char *argv[])
{
csApplication a(argc, argv);
();
}
点击运⾏就可以了。

本文发布于:2023-06-14 04:03:08,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1037540.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:函数   线程   代码   主线   可能
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图