Qt开发技巧(十一):优化项目文件管理,网络通信端口的唯一性,打开本地网络文件,网络请求的超时限制,Qt的三大工程类型,获取相机设备的配置参数,Qt时间格式输出

继续讲一些Qt开发中的技巧操作
1.优化项目文件管理
项目代码文件数量如果很多的话,全部包含在pro项目文件中会显得非常凌乱,甚至滚动条都要拉好久,有两个方法可以处理的更好,推荐用方法2

//方法1:pro文件中对于同目录的同类型文件,可以使用*直接全部引入,而不是每个文件都添加一次,省心省力。
HEADERS += *.h
SOURCES += *.cpp
//方法2:分模块文件夹存放,不同模块用pri包含代码文件,比如界面可以放在ui文件夹,下面搞个
ui.pri,然后pro项目文件只需要引入这个pri文件即可。
include($$PWD/ui/ui.pri)
//还可以加上一句包含路径这样可以省去在使用代码的时候不用写文件夹
INCLUDEPATH += $$PWD/ui
//加上上面这行,在使用头文件的时候可以直接 include "form.h",没有加则需要 include "ui/form.h"

2.网络通信端口的唯一性
关于网络通信,tcp和udp是两种不同的底层的网络通信协议,两者监听和通信的端口互不相干的,不同的协议或者不同的网卡IP地址可以用相同的端口。之前有个人说他的电脑居然可以监听一样的端口进行通信,书上说的明明是不可以相同端口的,其实是选择的不同的网卡IP地址下的,当然可以同一端口,就相当于C盘下的test.txt和D盘下的test.txt,不可能冲突。
就是说:
tcp对网卡1监听了端口9527,还可以对网卡2监听端口9527;
tcp对网卡1监听了端口9527,udp对网卡1还可以继续监听端口9527;
tcp对网卡1监听了端口9527,在网卡1上其他tcp就只能监听9527以外的端口,这里必须保证唯一性!!!
udp对网卡1监听了端口9527,在网卡1上其他udp就只能监听9527以外的端口,这里必须保证唯一性!!!
3.打开本地网络文件
在Qt中打开本地网络文件用QDesktopServices::openUrl();Qt中设置或者打开加载本地文件需要用到QUrl类,本地文件建议加上 file:/// 前缀。

QString url = "file:///c:/1.html";
//浏览器控件打开本地网页文件
webView->setUrl(QUrl(url));
//打开本地网页文件,下面两种方法都可以
QDesktopServices::openUrl(QUrl::fromLocalFile(url));
QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode));

4.网络请求的超时限制
在网络请求中经常涉及到超时时间的问题,因为默认是30秒钟,一旦遇到网络故障的时候要等好久才能反应过来,所以需要主动设置下超时时间,超过了就直接中断结束请求。从Qt5.15开始内置了setTransferTimeout来设置超时时间,非常好用。

//局部的事件循环,不卡主界面
QEventLoop eventLoop;
//设置超时 5.15开始自带了超时时间函数 默认30秒
#if (QT_VERSION >= QT_VERSION_CHECK(5,15,0))
manager->setTransferTimeout(timeout);
#else
QTimer timer;
connect(&timer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
timer.setSingleShot(true);
timer.start(timeout);
#endif
QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(url)));
connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
eventLoop.exec();
if (reply->bytesAvailable() > 0 && reply->error() == QNetworkReply::NoError)
{
//读取所有数据保存成文件
QByteArray data = reply->readAll();
QFile file(dirName + fileName);
if (file.open(QFile::WriteOnly | QFile::Truncate)) {
file.write(data);
file.close();
}
}

5.Qt的三大工程类型
Qt中基本上有三大类型的项目,控制台项目对应QCoreApplication、传统QWidget界面程序对应QApplication、quick/qml项目程序对应QGuiApplication。有很多属性的开启需要在main函数的最前面执行才有效果,比如开启高分屏支持、设置opengl模式等。不同类型的项目需要对应的QApplication。

//如果是控制台程序则下面的QApplication换成QCoreApplication
//如果是quick/qml程序则下面的QApplication换成QGuiApplication
int main(int argc, char *argv[])
{
//可以用下面这行测试Qt自带的输入法软键盘 qtvirtualkeyboard
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
//设置不应用操作系统设置比如字体
QApplication::setDesktopSettingsAware(false);
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
//设置高分屏缩放舍入策略
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRou
ndingPolicy::Floor);
#endif
#if (QT_VERSION > QT_VERSION_CHECK(5,6,0))
//设置启用高分屏缩放支持
//要注意开启后计算到的控件或界面宽度高度可能都不对,全部需要用缩放比例运算下
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
//设置启用高分屏图片支持
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif
#if (QT_VERSION > QT_VERSION_CHECK(5,4,0))
//设置opengl模式 AA_UseDesktopOpenGL(默认) AA_UseOpenGLES
AA_UseSoftwareOpenGL
//在一些很旧的设备上或者对opengl支持很低的设备上需要使用AA_UseOpenGLES表示禁用硬件
加速
//如果开启的是AA_UseOpenGLES则无法使用硬件加速比如ffmpeg的dxva2
//QApplication::setAttribute(Qt::AA_UseOpenGLES);
//设置opengl共享上下文
QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
#endif
QApplication a(argc, argv);
QWidget w;
w.show();
return a.exec();
}

6.获取相机设备的配置参数
QCamera中获取设备的配置参数比如支持的分辨率集合等,需要先调用load后才能正确获取,或者关联stateChanged信号中判断状态是否是ActiveState,然后再读取。

//方法1:调用load后获取
camera = new QCamera(this);
//先需要载入才能获取到对应参数
camera->load();
//输出当前设备支持的分辨率
QList<QSize> sizes = camera->supportedViewfinderResolutions();
emit resolutions(sizes);
//重新设置分辨率
QCameraViewfinderSettings set;
set.setResolution(cameraWidth, cameraHeight);
camera->setViewfinderSettings(set);
//获取完成后卸载
camera->unload();
//方法2:通过事件信号获取
camera = new QCamera(this);
connect(camera, SIGNAL(stateChanged(QCamera::State)), this,
SLOT(stateChanged(QCamera::State)));
void CameraThread::stateChanged(QCamera::State state)
{
if (state == QCamera::ActiveState) {
//输出当前设备支持的分辨率
QList<QSize> sizes = camera->supportedViewfinderResolutions();
emit resolutions(sizes);
//重新设置分辨率
QCameraViewfinderSettings set;
set.setResolution(cameraWidth, cameraHeight);
camera->setViewfinderSettings(set);
}
}
//QCamera没有指定设备名称的时候则采用默认的摄像机
camera = new QCamera(this);
//cameraName = @device:pnp:\\\\?
\\usb#vid_046d&pid_0825&mi_00#6&212eebd3&0&0000#{65e8773d-8f56-11d0-a3b9-
00a0c9223196}\\global
//可以通过设备描述符来查找设备名称(唯一标识)
camera = new QCamera(cameraName.toUtf8(), this);

7.Qt时间格式输出
QDateTime可以直接格式化输出星期几周几,Qt6默认按照英文输出比如 ddd = 周二 Tue dddd = 星期二 Tuesday ,此时如果只想永远是中文就需要用到QLocale进行转换。

//格式化输出受到本地操作系统语言的影响
//英文操作系统
//这样获取到的是Mon到Sun,英文星期的3个字母的缩写。
QDateTime::currentDateTime().toString("ddd");
//这样获取到的是Monday到Sunday,英文星期完整单词。
QDateTime::currentDateTime().toString("dddd");
//中文操作系统
//这样获取到的是周一到周日。
QDateTime::currentDateTime().toString("ddd");
//这样获取到的是星期一到星期日。
QDateTime::currentDateTime().toString("dddd");
//主动指定语言转换
//如果没有指定本地语言则默认采用系统的语言环境。
QLocale locale;
//QLocale locale = QLocale::Chinese;
//QLocale locale = QLocale::English;
//QLocale locale = QLocale::Japanese;
//下面永远输出中文的周一到周日
locale.toString(QDateTime::currentDateTime(), "ddd");
//下面永远输出中文的星期一到星期日
locale.toString(QDateTime::currentDateTime(), "dddd");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值