Qt启动动画

QSplashScreen

这个测试的时候发现仅仅是用于播放启动动画,并不能在启动动画显示的时候进行初始化过程,于是想了一个另外的方法进行启动动画的实现。

另开一个线程执行初始化过程

可以新开一个线程用于专门的数据初始化过程,测试的时候发现在新开的线程中对界面相关的类进行操作时会出现程序报错问题,因此架构设计为主main()函数所在线程用于单独的启动动画显示,然后新开的线程负责数据初始化:

#include "mainwindow.h"
#include <QApplication>
#include <startupwidget.h>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    g_mainWindow = new MainWindow;

    StartupWidget startupWdiget;
    StartupThread thread(&startupWdiget);
    
    startupWdiget.show();
    thread.start();         // 执行与界面无关的初始化过程

    a.exec();

    initUI();				// 执行与界面有关的初始化过程

    g_mainWindow->show();

    return a.exec();
}

MainWindow源码:

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    // 将整个初始化过程拆分为两个阶段,一个阶段是启动过程( startup() ),这个过程用于加载和界面无关的资源;另一个过程初始化界面资源,根本原因就是不能使用多线程操作UI资源。
    void startup();
    void initUI();

private:
    Ui::MainWindow *ui;
};

extern MainWindow *g_mainWindow;

#endif // MAINWINDOW_H

mainwindow.c++:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "unistd.h"

MainWindow *g_mainWindow;


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::startup()
{
    sleep(3);
}


void MainWindow::initUI()
{
    ui->lineEdit->setText("1");
}

StartUpWidget源码

startupwidget.h

#ifndef STARTUPWIDGET_H
#define STARTUPWIDGET_H

#include <QWidget>
#include <QThread>
#include <QTimer>

namespace Ui {
class StartupWidget;
}

class StartupWidget : public QWidget
{
    Q_OBJECT

public:
    explicit StartupWidget(QWidget *parent = nullptr);
    ~StartupWidget();
    void setExitUI();

private slots:
    void updateUI();

private:
    Ui::StartupWidget *ui;
    QTimer *m_timer;
    bool m_exitFlag;
};

class StartupThread : public QThread
{
public:
    StartupThread(StartupWidget *widget);

protected:
    void run();

private:
    StartupWidget *m_widget;
};

void initUI();


#endif // STARTUPWIDGET_H

startupwidget.c++

#include "startupwidget.h"
#include "ui_startupwidget.h"
#include "unistd.h"
#include <mainwindow.h>

StartupWidget::StartupWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::StartupWidget),
    m_exitFlag(false)
{
    ui->setupUi(this);

    m_timer = new QTimer(this);
    connect(m_timer, SIGNAL(timeout()), this, SLOT(updateUI()));
    m_timer->start(300);
}

StartupWidget::~StartupWidget()
{
    delete ui;
}

void StartupWidget::setExitUI()
{
    m_exitFlag = true;
}

void StartupWidget::updateUI()
{
    if(m_exitFlag)      close();
}

StartupThread::StartupThread(StartupWidget *widget)
    : m_widget(widget)
{

}

void StartupThread::run()
{
    g_mainWindow->startup();

    // 设置退出启动动画,使用定时器机制推出就一定可以在第一个QApplication::exec()的时候执行close(),这里直接close掉可能有界面线程还没运行到exec(),这里就close(),导致整个进程卡在main()中第一个QApplication::exec()位置
    m_widget->setExitUI();
    return;
}

char *code = "b90b8b74-2016-4d8a-86f5-7ef42a246d86";
void initUI()
{
    g_mainWindow->initUI();
}

总结

核心就是使用两个exec(),第一个用于阻塞启动动画的显示,当初始化线程完成初始化工作后间接调用启动动画的close()从而进入到程序界面exec()位置。从而实现在启动动画显示过程中加载一些与界面无关的、较耗时的资源初始化工作。

posted @   呵哈呵  阅读(160)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示