目录
QSplashScreen 类介绍
使用方式
项目中使用
THPrinterSplashScreen头文件
THPrinterSplashScreen实现代码
使用代码
使用效果
QSplashScreen 类介绍
QSplashScreen 是 Qt 中的一个类,用于显示启动画面。它通常在应用程序启动时显示,以向用户显示应用程序正在启动的状态。启动画面可以是一个图片,也可以是一个包含了文本、图片等内容的窗口。
QSplashScreen(const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = Qt::WindowFlags())
QSplashScreen(QWidget *parent, const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = Qt::WindowFlags())
virtual ~QSplashScreen()
void finish(QWidget *mainWin)QString message() const
const QPixmap pixmap() const
void repaint()
void setPixmap(const QPixmap &pixmap)//slots
void clearMessage()
void showMessage(const QString &message, int alignment = Qt::AlignLeft, const QColor &color = Qt::black)//protected 可以继承自绘
virtual void drawContents(QPainter *painter)
使用方式
以下是Qt官方文档给出的两种使用场景。
作为主窗口启动前的启动动画
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QPixmap pixmap(":/splash.png");
QSplashScreen splash(pixmap);
splash.show();
app.processEvents();
...
QMainWindow window;
window.show();
splash.finish(&window);
return app.exec();
}
主窗口启动前软件启动提示信息
QPixmap pixmap(":/splash.png");
QSplashScreen *splash = new QSplashScreen(pixmap);
splash->show();
... // Loading some items
splash->showMessage("Loaded modules");
qApp->processEvents();
... // Establishing connections
splash->showMessage("Established connections");
qApp->processEvents();
项目中使用
实际项目中如果软件启动比较耗时,一般需要根据软件的样式风格和互动需求自定义启动动画效果,此时virtual void drawContents(QPainter *painter) 和 repaint()就显得尤为重要。
以下是根据自身项目,加载启动动画时显示软件版本信息和启动进度等信息,主要继承drawContents进行重绘。
THPrinterSplashScreen头文件
#ifndef THPrinterSplashScreenT_H
#define THPrinterSplashScreenT_H
#include <QSplashScreen>
#include "Common.h"
#define g_pSplashScreen Singleton<THPrinterSplashScreen>::getInstance()
class THPrinterSplashScreen : public QSplashScreen
{
Q_OBJECT
friend Singleton<THPrinterSplashScreen>;
public:
//关闭自身前可以再次操作
void finish(QWidget *w);
//设置启动进度0-100
void setProgressValue(int value);
//设置启动提示信息 如库加载信息、数据库启动...
void setTipStr(const QString&tipStr);
protected:
//重写此函数 自定义绘制启动动画
void drawContents(QPainter *painter) override;
private:
THPrinterSplashScreen();
~THPrinterSplashScreen() = default;
QPixmap m_pixIcon;
QPixmap m_picBackground;
int m_nProgressValue = 0;
QString m_strTip;
};
#endif // THPrinterSplashScreenT_H
THPrinterSplashScreen实现代码
#pragma execution_character_set("utf-8")
THPrinterSplashScreen::THPrinterSplashScreen()
{
m_picBackground.load(":/images/icon/background.png");
m_pixIcon.load(":/images/icon/logo.png");
setPixmap(m_picBackground);
setWindowFlag(Qt::WindowStaysOnTopHint);
}
void THPrinterSplashScreen::finish(QWidget *w)
{
setProgressValue(100);
setTipStr("程序加载完成!");
QSplashScreen::finish(w);
}
void THPrinterSplashScreen::setProgressValue(int value)
{
if (isVisible() && value >= 0 && m_nProgressValue < value) {
value = qBound(0, value,100);
m_nProgressValue = value;
repaint();
}
}
void THPrinterSplashScreen::setTipStr(const QString&tipStr)
{
if (isVisible() && !tipStr.isEmpty() && m_strTip != tipStr) {
m_strTip = tipStr;
repaint();
}
}
void THPrinterSplashScreen::drawContents(QPainter *painter)
{
QSplashScreen::drawContents(painter);
int bg_w = m_picBackground.width();
int bg_h = m_picBackground.height();
int icon_w = m_pixIcon.width();
int icon_h = m_pixIcon.height();
//默认垂直方向dpi为96 防止不同设备分辨率不同字体差异过大
float fFactor = logicalDpiY() / 96.0f;
int smallFontSize = qRound(10 * fFactor);
int midFontSize = qRound(15 * fFactor);
int bigFontSize = qRound(20 * fFactor);
int fontGapSize = 6;
int magrinGapSize = 10;
int offset = -20;
int icon_x = (bg_w - icon_w) / 2;
int icon_y = (bg_h - icon_h) / 2 + offset;
int text_name_y = (bg_h + icon_h) / 2 + magrinGapSize + offset;
int text_TipStr_y = text_name_y + bigFontSize + fontGapSize;
int text_version_y = bg_h - fontGapSize - midFontSize;
QRect rect_Icon(icon_x, icon_y, icon_w, icon_h);//相对于parent 左上角坐标 长宽
QRect rect_Name_Text(0, text_name_y, bg_w, bigFontSize + fontGapSize);
QRect rect_TipStr_Text(0, text_TipStr_y, bg_w, smallFontSize + fontGapSize);
QRect rect_Version_Text(0, text_version_y, bg_w, midFontSize + fontGapSize);
// 绘制启动动画logo
painter->drawPixmap(rect_Icon, m_pixIcon);
//绘制软件名称
auto font = painter->font();
font.setBold(true);
font.setPointSize(bigFontSize);
painter->setFont(font);
auto pen = painter->pen();
pen.setColor(Qt::white);
painter->setPen(pen);
painter->drawText(rect_Name_Text, Qt::AlignCenter, tr("设备指纹烧录工具"));
//绘制启动中提示信息
font = painter->font();
font.setBold(false);
font.setPointSize(smallFontSize);
painter->setFont(font);
if (!m_strTip.isEmpty())
{
painter->drawText(rect_TipStr_Text, Qt::AlignCenter, m_strTip);
}
//绘制软件版本信息
font = painter->font();
font.setPointSize(midFontSize);
painter->setFont(font);
auto &strVersion = PmsUpDater::getVersion();
if (!strVersion.isEmpty()) {
painter->drawText(rect_Version_Text, Qt::AlignCenter, strVersion);
}
//在rect_Version_Text最右侧绘制软件启动进度
if (m_nProgressValue >= 0) {
rect_Version_Text.adjust(0, 0, -midFontSize, 0);
painter->drawText(rect_Version_Text,
Qt::AlignVCenter | Qt::AlignRight,
QString("%1%").arg(m_nProgressValue));
}
}
使用代码
main函数中嵌入到软件主界面启动前后。
int main(int argc, char *argv[])
{
//...
g_pSplashScreen->setProgressValue(0);
g_pSplashScreen->show();
PmsUpDater w;
w.show();
g_pSplashScreen->finish(&w);
//...
return a.exec();
}
在程序启动比较耗时的地方添加进度信息和提示信息,便于判断程序启动的状态,若程序启动失败也可作为定位失败位置的信息。
int THPrinter::Initial()
{
//...
//初始化SDK
InitialSdk();
g_pSplashScreen->setTipStr("SDK初始化成功!");
g_pSplashScreen->setProgressValue(53);
//...
//数据库连接开始
g_pSplashScreen->setTipStr("数据库连接中...");
g_pSplashScreen->setProgressValue(56);
//...
//连接完成
g_pSplashScreen->setTipStr("数据库连完成");
g_pSplashScreen->setProgressValue(57);
//...
}