精华内容
下载资源
问答
  • Qt启动多线程

    2020-12-03 15:11:07
    Qt启动多线程 项目需要在Qt进入启动页之前加载一大模型文件,同时要有一页面用来提示用户加载状态。 这里就需要用到多线程了,如果在单线程操作,要么需要等到文件加载完毕后才能显示等待页,要么干脆跳过了...

    Qt启动页多线程

    项目需要在Qt进入启动页之前加载一个大模型文件,同时要有一个页面用来提示用户加载状态。

    这里就需要用到多线程了,如果在单线程操作,要么需要等到文件加载完毕后才能显示等待页,要么干脆跳过了模型文件的加载,都是不符合需求的。

    我们通过代码分析。

    首先要绘制加载页,这里做一个非常简单的等待页,只有一行Loading…,可根据需求修改。
    waiting.h

    #ifndef WAITING_H
    #define WAITING_H
    
    #include <QDialog>
    #include <QLabel>
    #include <QMovie>
    
    class Waiting : public QDialog
    {
        Q_OBJECT
    public:
        explicit Waiting(QDialog *parent = 0);
    
    private:
        QLabel *label;
    
    };
    
    #endif // WAITING_H
    
    

    waiting.cpp

    #include <waiting.h>
    
    Waiting::Waiting(QDialog *parent):
        QDialog(parent)
    {
        this -> setWindowFlags ( Qt ::FramelessWindowHint );
        //this->setWindowOpacity(1);
        setFixedSize(320,180);
    
        //提示Label
        label = new QLabel(this);
        label -> setGeometry(0,0,320,180);
        label -> setText("Loading...");
        label -> setScaledContents(true);
        label -> setAlignment(Qt::AlignCenter);
        label -> setStyleSheet("font-size:24pt;color:#1644B0");
    }
    
    

    然后就需要写多线程了,这里需要注意,一定要把费事费力的操作放在子线程里,否则会造成主线程阻塞卡死!!
    waitingthread.h

    #ifndef WAITINGTHREAD_H
    #define WAITINGTHREAD_H
    
    #include <QThread>
    #include <QDebug>
    #include "大文件api"
    
    extern 大文件api;
    
    class waitingThread : public QThread
    {
        Q_OBJECT
    
    public:
        explicit waitingThread(QObject *parent = nullptr);
    
        void run(); //任务处理线程
        bool isStop;//线程工作标志
    };
    
    #endif // WAITINGTHREAD_H
    
    

    waitingthread.cpp

    #include "waitingthread.h"
    #include "waiting.h"
    
    waitingThread::waitingThread(QObject *parent)
    {
        isStop = false;
    }
    
    void waitingThread::run()	//子线程核心操作放在这里
    {
        大文件api.init(); // initialize API
        isStop = true;
    }
    
    

    然后就是在主程序里操作了。这里需要注意的点也很多,先放代码。

    #include <QApplication>
    #include <QThread>
    #include <跳转页.h>
    #include <waitingthread.h>
    #include <waiting.h>
    #include "大文件api"
    
    大文件api声明;
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        waitingThread *wt = new waitingThread;
        wt -> start();
    
        Waiting *w = new Waiting();
        w -> show();
    
        while(true){
            if(wt -> isStop == true)
            {
            	w -> close();
                //从屏保页开始
                new跳转页;
                跳转页 -> show();
                break;
        
            }else{
                QEventLoop eventloop;
                QTimer::singleShot(1000, &eventloop, SLOT(quit())); //wait 1s
                eventloop.exec();
            }
        }
        return a.exec();
    }
    

    首先要先执行子线程,后台开始处理加载大文件操作。然后显示等待页面,直到大文件加载完,加载标记isStop变为true的时候,再进入跳转页。顺序很重要。

    因为要连续地判断加载标记当前的状态,因此这里需要用到死循环。但是单纯的死循环必定会造成主程序阻塞卡死,导致等待页也显示不出来,因此需要在死循环中加入阻塞,防止卡死。

    阻塞如果使用sleep(),理论上也可以,但这里会导致我的Label刷新不出来,等待页还是不能正确显示。所以这里用了QEventLoop和QTimer的singleShot,死循环到这里每次阻塞1秒的时间,这样等待页面waiting就可以正确加载出来了。

    展开全文
  • Qt开启多线程

    千次阅读 2019-04-23 09:42:58
    Qt开启多线程,主要用到类QThread。有两种方法,第一种用一类继承QThread,然后重新改写虚函数run()。当要开启新线程时,只需要实例该类,然后调用函数start(),就可以开启一条多线程。第二种方法是继承一...

    Qt开启多线程,主要用到类QThread。有两种方法,第一种用一个类继承QThread,然后重新改写虚函数run()。当要开启新线程时,只需要实例该类,然后调用函数start(),就可以开启一条多线程。第二种方法是继承一个QObject类,然后利用moveToThread()函数开启一个线程槽函数,将要花费大量时间计算的代码放入该线程槽函数中。第二种方法可以参考我写的另一篇博客:https://blog.csdn.net/naibozhuan3744/article/details/81201502。

    下面我总结的主要是第一种方法。(注意:只有在run()函数里面才是新的线程,所有复杂逻辑都应该在run()函数里面做。当run()函数运行完毕后,该线程生命周期结束。)

    创建多线程步骤如下:

    a1新建一个类MyThread,基类为QThread。

    a2重写类MyThread的虚函数void run();,即新建一个函数protected void run(),然后对其进行定义。

    a3在需要用到多线程的地方,实例MyThread,然后调用函数MyThread::start()后,则开启一条线程,自动运行函数run()。

    a4当停止线程时,调用MyThread::wait()函数,等待线程结束,并且回收线程资源。

     

    1.1新建一个widget工程,不要勾选ui界面。然后分别在mythread.h,mythread.cpp,widget.h,widget.cpp,main.cpp分别添加如下代码。

    mythread.h

    #ifndef MYTHREAD_H
    #define MYTHREAD_H
     
    #include <QThread>
     
    class MyThread : public QThread
    {
    public:
        MyThread();
        void closeThread();
     
    protected:
        virtual void run();
     
    private:
        volatile bool isStop;       //isStop是易失性变量,需要用volatile进行申明
    };
     
    #endif // MYTHREAD_H


     

    mythread.cpp

    #include "mythread.h"
    #include <QDebug>
    #include <QMutex>
     
    MyThread::MyThread()
    {
        isStop = false;
    }
     
    void MyThread::closeThread()
    {
        isStop = true;
    }
     
    void MyThread::run()
    {
        while (1)
        {
            if(isStop)
                return;
            qDebug()<<tr("mythread QThread::currentThreadId()==")<<QThread::currentThreadId();
            sleep(1);
        }
    }
    

    widget.h

    #ifndef WIDGET_H
    #define WIDGET_H
     
    #include <QWidget>
    #include <mythread.h>
    #include <QPushButton>
    #include <QVBoxLayout>
    #include <QMutex>
     
    class Widget : public QWidget
    {
        Q_OBJECT
     
    public:
        Widget(QWidget *parent = 0);
        ~Widget();
        void createView();
     
    private slots:
        void openThreadBtnSlot();
        void closeThreadBtnSlot();
        void finishedThreadBtnSlot();
    //    void testBtnSlot();
     
    private:
        QVBoxLayout *mainLayout;    
        MyThread *thread1;
    };
     
    #endif // WIDGET_H
    

    widget.cpp

    #include "widget.h"
    #include <QDebug>
    #include <windows.h>
     
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
    {
        createView();
    }
     
    void Widget::createView()
    {
        /*添加界面*/    
        QPushButton *openThreadBtn = new QPushButton(tr("打开线程"));
        QPushButton *closeThreadBtn = new QPushButton(tr("关闭线程"));
        mainLayout = new QVBoxLayout(this);
        mainLayout->addWidget(openThreadBtn);
        mainLayout->addWidget(closeThreadBtn);
        mainLayout->addStretch();
        connect(openThreadBtn,SIGNAL(clicked(bool)),this,SLOT(openThreadBtnSlot()));
        connect(closeThreadBtn,SIGNAL(clicked(bool)),this,SLOT(closeThreadBtnSlot()));    
     
        /*线程初始化*/
        thread1 = new MyThread;
        connect(thread1,SIGNAL(finished()),this,SLOT(finishedThreadBtnSlot()));
    }
     
    void Widget::openThreadBtnSlot()
    {
        /*开启一个线程*/    
        thread1->start();
        qDebug()<<"主线程id:"<<QThread::currentThreadId();
    }
     
    void Widget::closeThreadBtnSlot()
    {
        /*关闭多线程*/
        thread1->closeThread();
        thread1->wait();
    }
     
    void Widget::finishedThreadBtnSlot()
    {
        qDebug()<<tr("完成信号finished触发");
    }
     
    Widget::~Widget()
    {
    }
    

    main.cpp

    #include "widget.h"
    #include <QApplication>
     
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Widget w;
        w.resize(960,640);
        w.show();
     
        return a.exec();
    }
    

    1.2程序构建和运行后,结果如下图所示:

     

     

     

     

    参考内容:

    https://blog.csdn.net/czyt1988/article/details/64441443(正确终止线程经典教程)

    https://blog.csdn.net/MyCodingLine/article/details/48597935

    https://blog.csdn.net/xipiaoyouzi/article/details/8450704

    https://blog.csdn.net/qq769651718/article/details/79357933(两种创建多线程方式)

    https://blog.csdn.net/czyt1988/article/details/71194457
    --------------------- 
    作者:净无邪 
    来源:CSDN 
    原文:https://blog.csdn.net/naibozhuan3744/article/details/81174681 
     

    展开全文
  • QT开启多个工作线程

    千次阅读 热门讨论 2019-04-23 14:27:19
    开启多线程: m_tThread = new zzcThread[50]; int i = 0; for (;i ;) { connect(this,SIGNAL(GetGuiThreadId(int)),&m_tThread[i],SLOT(onGetGuiThreadId(int))); emit GetGuiThreadId(i); ...

    采用继承QThread的方法:

    #ifndef ZZCTHREAD_H
    #define ZZCTHREAD_H
    
    #include <QThread>
    
    class zzcThread : public QThread
    {
    	Q_OBJECT
    
    public:
    	zzcThread(QObject *parent = NULL);
    	~zzcThread();
    
    	void run();
    
    public slots:
    	void onGetGuiThreadId(int nThreadId);
    
    private:
    	int m_nThreadID;
    	
    };
    
    #endif // ZZCTHREAD_H
    
    #include "zzcThread.h"
    #include <QDebug>
    
    zzcThread::zzcThread(QObject *parent)
    	: QThread(parent)
    {
    	m_nThreadID = 0;
    }
    
    zzcThread::~zzcThread()
    {
    
    }
    
    void zzcThread::run()
    {
    	qDebug() << "MyThreadId = " << QThread::currentThreadId() << "GUIThreadID =" << m_nThreadID << endl; 
    }
    
    void zzcThread::onGetGuiThreadId(int nThreadId)
    {
    	m_nThreadID = nThreadId;
    }

    开启多线程:

    m_tThread = new zzcThread[50];
    
    	int i = 0;
    
    	for (;i < 50;)
    	{
    		connect(this,SIGNAL(GetGuiThreadId(int)),&m_tThread[i],SLOT(onGetGuiThreadId(int)));
    
    		emit GetGuiThreadId(i);
    
    		disconnect(this,SIGNAL(GetGuiThreadId(int)),&m_tThread[i],SLOT(onGetGuiThreadId(int)));
    
    		m_tThread[i++].start();
    	}

    请注意:线程之间的运行顺序是不确定的

    展开全文
  • Qt5线程,实现一个线程的网络时间服务器,每当有客户请求,服务器将启动一个新线程为它返回当前时间,服务完毕后,这个线程自动退出。
  • 总结了一下Qt中sqlite多线程操作遇到的几问题,希望能对有需要的朋友一点帮助 总结了一下Qt中sqlite多线程操作遇到的几问题,希望能对有需要的朋友一点帮助
  • QT线程开发(二)——开启多个子线程方法 使用movetoThread方法。、 1、新建项目 新建MainWindow和MyThread。 2、代码如下 mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow&...

    QT多线程开发(二)——QT开启多个子线程方法

    使用movetoThread方法。、

    1、新建项目

    新建MainWindow和MyThread。
    在这里插入图片描述

    2、代码如下

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QThread>
    #include "mythread.h"
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    private slots:
        void on_pushButton_clicked();
    
        void on_pushButton_2_clicked();
    
    private:
        Ui::MainWindow *ui;
    
        QThread *m_Thread;
        MyThread *m_MyThread;
    signals:
        void signal01();
    
    };
    
    #endif // MAINWINDOW_H
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QDebug>
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        qDebug()<<"主线程号:"<<QThread::currentThread()<<QThread::currentThreadId();
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    //每点击一次按钮,新建一个子线程
    void MainWindow::on_pushButton_clicked()
    {
        qDebug()<<"新建线程";
        m_Thread = new QThread();
        m_MyThread = new MyThread();
        m_MyThread->moveToThread(m_Thread);
        connect(m_Thread,&QThread::finished,m_Thread,&QThread::deleteLater);
        connect(this,&MainWindow::signal01,m_MyThread,&MyThread::doSomething);
        m_Thread->start();
    
    }
    
    void MainWindow::on_pushButton_2_clicked()
    {
        qDebug()<<"信号";
        emit signal01();
    }
    

    mythread.h

    #ifndef MYTHREAD_H
    #define MYTHREAD_H
    
    #include <QObject>
    
    class MyThread : public QObject
    {
        Q_OBJECT
    public:
        explicit MyThread(QObject *parent = nullptr);
    
    signals:
    
    public slots:
        void doSomething();
    };
    
    #endif // MYTHREAD_H
    
    

    mythread.cpp

    #include "mythread.h"
    #include <QDebug>
    #include <QThread>
    
    MyThread::MyThread(QObject *parent) : QObject(parent)
    {
        qDebug()<<"MyThread"<<QThread::currentThread();
    }
    
    void MyThread::doSomething()
    {
        qDebug()<<"子线程号:"<<QThread::currentThread();
    }
    
    

    运行效果

    在这里插入图片描述

    不足之处

    这里没有将每次新建的子线程进行记录,会导致信号触发到所有新建的子线程中。下一步使用Vector将子线程记录下来,区分新建的子线程。

    展开全文
  • 每个QThread实例代表并控制一个线程。 QThread可以直接实例化也可以子类化。 实例化QThread提供了一个并行事件循环,从而允许在辅助线程中调用QObject槽。 子类化QThread允许应用程序在开始其事件循环之前初始化新...
  • QT (启动个线程)

    万次阅读 2018-12-01 17:06:47
    启动个线程的步骤: (1) 创建一个自己的线程类继承QT中的QThread类 创建线程类WorkThread; (2) 在自己的WorkThreak类中重新实现run()函数, 该函数是一个死循环, 主要是完成自己需要的功能代码 (3) 使用自己的类...
  • QT多线程

    2021-07-30 16:06:41
    如果程序中有比较费时的操作需要处理,由于只有一个线程存在,当你试着拖拽界面的时候就会出现卡顿。为了处理复杂的操作,我们必须引入线程。 一、任务分工 主线程:QT中默认的线程,也叫窗口线程,负责窗口事件...
  • Qt中的多线程编程

    2021-03-04 17:03:04
    Qt中的线程编程 **Qt4.7之后方法: 特点:使用灵活 1.业务类:** 1.1要在子线程中处理的业务操作抽象成一个类(SubThreadWork)(***继承于QObject)** ... 2.1在主线程中创建一个线程对象作为子线程使用QThread
  • Qt中的多线程技术

    2017-08-11 10:05:59
    Qt中的多线程技术 可以参考这篇文档,来选择合适的多线程方案。
  • Qt 多线程

    2021-07-27 17:20:17
    Qt中实现多线程往往是构造一数据处理类(继承Qobject),然后新建一对象,将其依附于子线程(通过movetothread(QThread*)成员函数),通过signal-slot实现多线程。为何不是新建一数据处理线程类来实现这过称? ...
  • Qt的QThread多线程使用

    千次阅读 2018-10-03 17:20:53
    最近开发某C++的AI项目,需要用到界面,为了计算过程不阻塞界面,需要使用多线程,在这里学习下Qt自带的多线程操作。 QThread是一与平台无关的线程类,用于多线程的编程。具体可以在文档中中索引QThread关键字。...
  • 4 如何正确启动个线程 41正确的启动一个全局线程和UI一直存在的线程 42 如何启动一个局部线程用完即释放的线程 继承QThread的一些总结 使用QObject实现线的方法见:http://blog.csdn.net/cz
  • Qt中的多线程

    2020-02-16 16:51:21
    通常情况下,应用程序都是在一个线程中执行操作。但是,当调用一个耗时操作(例如,大批量I/O或大量矩阵变换等CPU密集操作)时,用户界面常常会冻结。而使用线程可以解决这一问题。 线程有以下几个优势: 提高...
  • Cmake建立QT工程,开启多个线程接收UDP数据,使用UI显示 要做一个类似的工程,先做一个简单的验证,今天没时间细说了,先把所有的内容都放上,以后有时间了再解释。 具体实现的功能: 使用cmake建立qt的工程,有界面...
  • 个Qt5多线程的简单实例,工作线程类WorkThread继承自QThread类。
  • pstree 问题进程id查看当前面运行的各进程,对比代码发现,使用QTConcurrent启动线程有几未正常启动. 查询资料后发现,QTConcurrent使用了QThreadPool线程池创建的线程,而此线程池中的最大线程数默认值为QThread::...
  • QT多线程编程详解

    万次阅读 多人点赞 2019-04-24 22:08:20
    每个程序启动后拥有的第一个线程称为主线程,即GUI线程。QT中所有的组件类和几个相关的类只能工作在GUI线程,不能工作在次线程,次线程即工作线程,主要负责处理GUI线程卸下的工作。 2、数据的同步访问 每个线程都...
  • Qt多线程编程

    2020-06-23 17:29:25
    文章目录Qt多线程编程笔记1 程序、进程、线程的相关概念2 Qt多线程的使用(QThread)2.1 类中函数简介2.2 线程的生命周期2.3 多线程并发代码示例3 多线程间的同步3.1 同步的相关概念3.2 同步的代码展示4 多线程...
  • Qt多线程

    2021-06-02 21:48:12
    Qt多线程有两种方法: 1、定义一QThread的派生类,重写run函数,run函数中的程序就是新线程中要执行的内容。在主线程中实例化该类,调用start函数,就可以实现多线程。 2、定义一QObject的派生类,把要在新线程...
  • QT中的多线程编程

    千次阅读 2018-08-22 16:57:33
    目录 1、Qt中的多线程编程 2、多线程间的同步 3、多线程间的互斥 ... - QThread是一跨平台的多线程解决方案 - QThread以简洁易用的方式实现多线程编程 QThread中的关键成员函数 - void run...
  • Qt4 http多线程程序

    2014-04-11 15:49:57
    Qt4的多线程使用方法比较特殊,也使得编写多线程程序变的很简单,yo
  • Qt下实现多线程串口通信

    千次阅读 2019-05-20 07:19:37
    本文把每路串口的通信各放在一个线程中,使用movetoThread的方式实现。 用SerialPort类实现串口功能,Widget类调用串口。 serialport.h如下: #include <QObject> #include <QSerialPort>...
  • QT导出日志多线程

    2020-10-14 20:44:31
    Qt开发过程当中经常使用qDebug等一些输出来调试程序,但是到了正式发布的时候,都会被注释或者删除,采用日志输出来代替。 以下demo实现的功能: 将调试的log信息输出到文件log文件保存位置:当前程序运行的路径-&...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,369
精华内容 4,547
关键字:

qt开启多个线程