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就可以正确加载出来了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值