当程序加载较慢的时候,为了告知用户正在加载,需要在界面上显示正在加载中的提示。下面简单说一下自己使用中出现的问题。
一、在主线程中使用动画加载
创建基于qapplication的项目,以qdialog类为基类,有.ui文件。
项目的结构如下图所示:
需要自己在网上找一些加载中的动图存入gifs文件夹中,建立项目后,向项目中添加资源文件,即添加新文件-》添加qt资源文件-》添加资源文件的文件夹名(这里填写的是qrc)-》向其中添加前缀,添加文件,再保存。
下面是创建的一个小的demo,直接上代码。
main.cpp
#include "dialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
return a.exec();
}
上面的main.cpp采用的是自动生成的文件,未做任何改动。
dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QLabel>
#include <QMovie>
QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget *parent = nullptr);
~Dialog();
void loadingGif();
private:
Ui::Dialog *ui;
QLabel * m_label;
QLabel * m_textLabel;
QMovie * m_movie;
};
#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::Dialog)
{
ui->setupUi(this);
loadingGif();
}
Dialog::~Dialog()
{
m_movie->stop();
if(m_movie != nullptr)
{
delete m_movie;
m_movie = nullptr;
}
delete ui;
}
void Dialog::loadingGif()
{
m_label = new QLabel(this);
m_textLabel = new QLabel("正在加载......",this);
m_label->setGeometry(150,130,120,120);
m_textLabel->setGeometry(150,250,120,40);
m_movie = new QMovie(":/new/prefix1/gifs/771.gif");
m_label->setScaledContents(true);//缩放label使其适应其内容
m_label->setFixedSize(120,120);
m_label->setMovie(m_movie);
m_movie->start();
}
以上便是项目的源文件,运行程序后效果如下。
编译环境为:qtcreate5.13.2,编译器为MinGW32位。
二、通过子线程使用动画加载
也是创建基于qapplication的应用程序,基类位qdialog,包含ui文件。
文件的结构如下:
具体的代码如下:
mian.cpp
#include "dialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
return a.exec();
}
dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include "hintthread.h"
#include <QDialog>
#include <QLabel>
#include <QMovie>
#include <QVBoxLayout>
QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget *parent = nullptr);
~Dialog();
void diaplayHintMark();//显示正在更新的动画
public slots:
void slot_displayHintMark();
private:
Ui::Dialog *ui;
QLabel * m_label;
QMovie * m_movie;
QLabel * m_textLabel;
QVBoxLayout * m_layout;
hintThread * m_thread;
};
#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
#include <QDebug>
#include <QPalette>
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::Dialog)
{
ui->setupUi(this);
// this->setWindowFlags(Qt::FramelessWindowHint|Qt::WindowMinimizeButtonHint);
QPalette palette(this->palette());
palette.setColor(QPalette::Background, QColor(16,48,155,255));
this->setPalette(palette);
// this->setAttribute(Qt::WA_TranslucentBackground);
//创建线程,子线程更新提示
m_thread = new hintThread(this);
m_thread->start();
// diaplayHintMark();
}
Dialog::~Dialog()
{
m_movie->stop();
if(m_movie != nullptr)
{
delete m_movie;
m_movie = nullptr;
}
if(m_thread->isRunning())
{
m_thread->quit();
m_thread->wait();
if(m_thread != nullptr)
{
delete m_thread;
m_thread = nullptr;
}
}
else
{
if(m_thread != nullptr)
{
delete m_thread;
m_thread = nullptr;
}
}
delete ui;
}
void Dialog::diaplayHintMark()
{
qDebug()<<"开始加载";//ui->insideWidget
m_label = new QLabel(this/*,Qt::WindowStaysOnTopHint*/);
m_movie = new QMovie(":/new/prefix1/gifs/771.gif");
m_label->setGeometry(QRect(100,100,120,120));
m_label->setFixedSize(120,120);
m_label->setScaledContents(true);
m_label->setMovie(m_movie);
m_textLabel = new QLabel("努力加载中,请稍后.....",this);
m_textLabel->setGeometry(100,220,300,40);
m_label->show();//没有调用显示函数
m_textLabel->show();
m_movie->start();
qDebug()<<"你好。。。。!";
qDebug()<<"what should i do。。。。!";
}
void Dialog::slot_displayHintMark()
{
diaplayHintMark();
}
hintthread.h
#ifndef HINTTHREAD_H
#define HINTTHREAD_H
#include <QThread>
class Dialog;
class hintThread : public QThread
{
Q_OBJECT
public:
hintThread(Dialog * dlg);
hintThread(QObject* parent = 0);
signals:
void signalDisplayHintMark();
public slots:
void slot_displayHintMark();
protected:
void run();
private:
Dialog * m_dlg;
};
#endif // HINTTHREAD_H
hintthread.cpp
#include "hintthread.h"
#include "dialog.h"
hintThread::hintThread(Dialog * dlg)
:QThread()
{
m_dlg = dlg;//以下两种信号槽绑定都可以
// connect(this,SIGNAL(signalDisplayHintMark()),m_dlg,SLOT(slot_displayHintMark()));
connect(this,SIGNAL(signalDisplayHintMark()),this,SLOT(slot_displayHintMark()));
}
hintThread::hintThread(QObject* parent)
: QThread(parent)
{
}
void hintThread::slot_displayHintMark()
{
m_dlg->diaplayHintMark();
}
void hintThread::run()
{
emit signalDisplayHintMark();
}
程序的运行效果和上面类似 。第二个例子中通过创建子线程时传入主线程的指针,在子线程中发出信号,通过主线程指针调取主线程ui中的函数。上面第二个例子中,diaplayHintMark()函数未调用两个label的show()显示时,无法正常的显示,此时,函数中label也已设置了父窗口,但没法显示。在第一个例子中,也只是设置了label的父窗口,没有调用show(),可以显示,没想明白是什么原因,望知情者告知。