Qt开发技巧(七)动态换图,QVideoWidget视频闪烁,Qt日志打印,系统消息处理,编译前后的操作,QSettings配置文件,屏幕自适应

1.动态换图

Qt开发时,有时候我们在界面上需要动态的切换图片,比如接到来自底层驱动的信号分成告警信号,正常信号,危险信号,在界面上使用QLabel通过贴图来表示不同的信号,这时候尽量使用setStyleSheet(),而不是setPixmap();

正常情况下你不会看到差别,但在某个特定条件下,你会发现不一样。比如你用QLabel显示上述不同信号的图片场景,当你使用setPixmap();来显示图片时,一旦你设置QLabel禁用,你会发现你图片的展示变成了一个很奇怪的背景了,而使用setStyleSheet();却不会被禁用干扰。

cpp 复制代码
            QPixmap pixmap;
            QString strStyle;
            switch (state)
            {
            case State_Normal:
                pixmap.load(":/image/Image/label_green.png");
                strStyle = QString("QLabel{border-image: url(:/image/Image/label_green.png)");
                break;
            case State_Warn:
                pixmap.load(":/image/Image/label_yellow.png");
                strStyle = QString("QLabel{border-image: url(:/image/Image/label_yellow.png)");
                break;
            case State_Danger:
                pixmap.load(":/image/Image/label_red.png");
                strStyle = QString("QLabel{border-image: url(:/image/Image/label_red.png)");
                break;
            }
	//第一种使用setPixmap方式,当myLabel禁用后会变样
	myLabel->setPixmap(pixmap);
	//第二种使用setStyleSheet方式,当myLabel禁用后不会变样
	myLabel->setStyleSheet(strStyle);

2.QVideoWidget视频播放

QVideoWidget播放视频,可能会遇到画面闪烁的情况,播放视频的窗体需要设置个属性来解决这个问题。

cpp 复制代码
QVideoWidget *videoWidget = new QVideoWidget;
videoWidget->setAttribute(Qt::WA_OpaquePaintEvent);

3.Qt日志打印

Qt的调试功能其实很鸡肋,这就需要强大的日志辅助调试,Qt中想要打印日志,最简单的方式可以使用qDebug来打印调试,也可以使用其他几种打印信息比如 qInfo、qWarning、qCritical。

cpp 复制代码
qDebug() << "qDebug";
qInfo() << "qInfo";
qWarning() << "qWarning";
qCritical() << "qCritical";

如果不想要看到一堆堆的打印信息,可以在工程文件中禁用。

cpp 复制代码
#禁用qdebug打印输出
DEFINES += QT_NO_DEBUG_OUTPUT

这个宏会禁用qDebug输出,但qInfo、qWarning、qCritical不受影响。

如果需要长效的日志库,可以使用一些开源的第三方日志库,也可以自己写个日志库,这里推荐Qt的"log4qt"开源库,不仅可以打印用户写的日志,也能自行将Qt内部的一些警告错误打印出来,特别有助于分析问题。

4.系统消息处理

Qt对操作系统层的消息也做了很多的封装,可以直接拿到进行处理(如果需要拦截处理要用对应操作系统的API才行比如鼠标键盘钩子),比如系统休眠和唤醒做一些处理。

cpp 复制代码
//主窗体头文件
protected:
//处理原生窗口系统事件
bool nativeEvent(const QByteArray &eventType, void *message, long *result);
#ifdef Q_OS_WIN
//处理windows系统事件
bool winEvent(MSG *message, long *result);
#endif

//主窗体实现函数
#ifdef Q_OS_WIN
#include "Windows.h"
#endif
bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
if (eventType == "windows_generic_MSG")
{
#ifdef Q_OS_WIN
MSG *msg = static_cast<MSG *>(message);
//qDebug() << TIMEMS << msg->message;
if (msg->wParam == PBT_APMSUSPEND && msg->message == WM_POWERBROADCAST)
{
//系统休眠的时候自动最小化可以规避程序可能出现的问题
this->showMinimized();
} 
else if (msg->wParam == PBT_APMRESUMEAUTOMATIC) 
{
//休眠唤醒后自动打开
this->showNormal();
}
#endif
}
else if (eventType == "NSEvent")
{
#ifdef Q_OS_MACOS
#endif
}
return false;
}
#ifdef Q_OS_WIN
bool MainWindow::winEvent(MSG *message, long *result)
{
return nativeEvent("windows_generic_MSG", message, result);
}
#endif

5.编译前后的操作

Qt的.pro工程文件中提供了两个神奇的宏,可以在编译前和编译后分别做一些操作。

QMAKE_PRE_LINK 表示编译前执行内容

QMAKE_POST_LINK 表示编译后执行内容

比如下面这样执行一些拷贝操作

cpp 复制代码
srcFile1 = $$PWD/1.txt
srcFile2 = $$PWD/2.txt
dstDir = $$PWD/../bin
#windows上需要转换路径斜杠 linux等其他系统不需要
srcFile1 = $$replace(srcFile1, /, \\);
srcFile2 = $$replace(srcFile2, /, \\);
dstDir = $$replace(dstDir, /, \\);
#编译前执行拷贝 多个拷贝可以通过 && 符号隔开
QMAKE_PRE_LINK += copy /Y $$srcFile1 $$dstDir && copy /Y $$srcFile2 $$dstDir
#编译后执行拷贝 多个拷贝可以通过 && 符号隔开
QMAKE_POST_LINK += copy /Y $$srcFile1 $$dstDir && copy /Y $$srcFile2 $$dstDir

6.QSettings配置文件

QSettings是Qt中专门处理配置类文件数据而做的(当然也可以处理其他业务),用好QSettings可以方便快捷的处理配置类的相关操作。操作时注意,最好都以UTF-8编码方式处理,可以极大地避免中文乱码的情况。甚至整个Qt开发都最好全部用UTF-8编码,既统一了编码方式,也避免了编码转换,还能密码乱码问题。

cpp 复制代码
void App::readConfig()
{
QSettings set(App::ConfigFile, QSettings::IniFormat);
set.setIniCodec("utf-8");
set.beginGroup("MyConfig");
App::Company = set.value("version", App::version).toString();
set.endGroup();
}
void App::writeConfig()
{
QSettings set(App::ConfigFile, QSettings::IniFormat);
set.setIniCodec("utf-8");
set.beginGroup("MyConfig");
set.setValue("version", App::version);
set.endGroup();
}

7.屏幕自适应

在开发QT程序时,我们通常希望应用能够适应不同的屏幕分辨率,以确保用户在不同设备上都能够获得良好的使用体验。以下几种方式来处理不同分辨率下的自适应问题。

第一种:使用布局管理器:Qt提供了各种布局管理器,可以自动调整子控件的大小和位置以适应父控件的大小,从而实现适应屏幕的不同大小,有时候对有明显分辨率差异的屏幕效果很差。

第二种:使用QScreen和QDesktopWidget:获取当前屏幕的分辨率,并调整窗口大小以适应屏幕。

第三种:使用QResizeEvent:监听窗口大小改变事件,并在事件处理函数中实现自适应逻辑。

推荐使用第二种,根据屏幕的分辨率设置窗口大小,加之内部布局合理,这样比较容易适应屏幕。

cpp 复制代码
//Qt启动高分屏的方法
int main(int argc, char *argv[])
{
   QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
   //开启高缩放支持以后图片可能发虚还要开启下面这个属性
   QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
   QApplication a(argc, argv);
}
相关推荐
小_太_阳2 分钟前
Scala_【1】概述
开发语言·后端·scala·intellij-idea
向宇it3 分钟前
【从零开始入门unity游戏开发之——unity篇02】unity6基础入门——软件下载安装、Unity Hub配置、安装unity编辑器、许可证管理
开发语言·unity·c#·编辑器·游戏引擎
Kai HVZ37 分钟前
python爬虫----爬取视频实战
爬虫·python·音视频
古希腊掌管学习的神39 分钟前
[LeetCode-Python版]相向双指针——611. 有效三角形的个数
开发语言·python·leetcode
赵钰老师40 分钟前
【R语言遥感技术】“R+遥感”的水环境综合评价方法
开发语言·数据分析·r语言
就爱学编程1 小时前
重生之我在异世界学编程之C语言小项目:通讯录
c语言·开发语言·数据结构·算法
Oneforlove_twoforjob1 小时前
【Java基础面试题025】什么是Java的Integer缓存池?
java·开发语言·缓存
emoji1111111 小时前
前端对页面数据进行缓存
开发语言·前端·javascript
每天都要学信号1 小时前
Python(第一天)
开发语言·python
TENET信条1 小时前
day53 第十一章:图论part04
开发语言·c#·图论