Qt开发经验小技巧131-140
Qt新版本往往会带来一些头文件的更新,比如以前使用QPainter绘制,不需要额外包含QPainterPath头文件,而5.15版本开始就需要显示主动引入#include "qpainterpath.h"才行。
Qt6.0发布了,是个比较大的改动版本,很多基础的类或者组件都放到单独的源码包中,需要自行官网下载并编译,默认不提供集成在开发目录下,需要手动编译并集成,比如QRegExp,QTextCodec类,需要编译集成后pro文件 QT += core5compat 才能用, 具体说明在https://doc.qt.io/qt-6/qtcore5-index.html。
qDebug输出打印信息,默认会完整打印转义字符,例如:\ " \t \n" 等,所以当你发现你明明设置了转义字符以后打印确还是转义前的字符,这就懵逼了,其实这是qdebug为了方便调试将各种字符都打印输出。无可否认,很多时候,我们极其兴奋的享受着Qt带来的各种轮子各种便利,但是偶尔,稍不留意,这些便利可能也会坑你一把。要做的就是擦亮眼睛,时刻谨慎,一步一个脚印踏踏实实码代码。
QString s1 = R"(\:device0)";
//TNND居然输出的是 \\:device0
qDebug() << s1;
//这次终于正确的输出 \:device0
qDebug().noquote() << s1;
- 很多人有疑问为何qss对浏览器控件中的网页样式没法控制,其实用屁股想想也知道,那玩意是html css去控制的,和Qt一毛钱关系也没有,根本管不着,如果想要对滚动条样式设置,可以在网页代码中设置样式就行。
<style type="text/css">
::-webkit-scrollbar{width:0.8em;}
::-webkit-scrollbar-track{background:rgb(241,241,241);}
::-webkit-scrollbar-thumb{background:rgb(188,188,188);}
</style>
- Qt的ini配置文件默认不支持直接读写中文,需要手动设置下编码格式才行,强烈建议统一用utf-8编码,包括代码文件。
//设置了编码以后配置文件内容为 Company=上海物联网技术研究中心
//没有设置编码则配置文件内容为 Company=\xe4\xb8\x8a\xe6\xb5\xb7\xe7\x89\xa9\xe8\x81\x94\xe7\xbd\x91\xe6\x8a\x80\xe6\x9c\xaf\xe7\xa0\x94\xe7\xa9\xb6\xe4\xb8\xad\xe5\xbf\x83
void App::readConfig()
{
QSettings set(App::ConfigFile, QSettings::IniFormat);
set.setIniCodec("utf-8");
set.beginGroup("AppConfig1");
App::Company = set.value("Company", App::Company).toString();
set.endGroup();
}
void App::writeConfig()
{
QSettings set(App::ConfigFile, QSettings::IniFormat);
set.setIniCodec("utf-8");
set.beginGroup("AppConfig1");
set.setValue("Company", App::Company);
set.endGroup();
}
- 用Qt做安卓开发都会遇到权限的问题,早期的安卓版本可以直接通过 AndroidManifest.xml 配置文件来添加需要的权限,这样在安装app的时候就会提示该app需要哪些权限让用户同意,现在的安卓版本都改成了动态权限,需要在app运行的时候弹出提示让用户确认再有权限,Qt迎合了这种策略内置了动态申请权限的方法 QtAndroid::requestPermissionsSync。
//动态设置权限
bool checkPermission(const QString &permission)
{
#ifdef Q_OS_ANDROID
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
QtAndroid::PermissionResult result = QtAndroid::checkPermission(permission);
if (result == QtAndroid::PermissionResult::Denied) {
QtAndroid::requestPermissionsSync(QStringList() << permission);
result = QtAndroid::checkPermission(permission);
if (result == QtAndroid::PermissionResult::Denied) {
return false;
}
}
#endif
#endif
return true;
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//请求权限
checkPermission("android.permission.READ_EXTERNAL_STORAGE");
checkPermission("android.permission.WRITE_EXTERNAL_STORAGE");
return a.exec();
}
- Qt重载qDebug输出自定义的信息。
struct FunctionInfo {
QString function;
QString name;
QString groupEnabled;
QString action;
QString group;
friend QDebug operator << (QDebug debug, const FunctionInfo &functionInfo) {
QString info = QString("功能: %1 名称: %2 启用: %3 方法: %4 分组: %5")
.arg(functionInfo.function).arg(functionInfo.name).arg(functionInfo.groupEnabled)
.arg(functionInfo.action).arg(functionInfo.group);
debug << info;
return debug;
}
};
- 对高分屏不同缩放比例的自适应处理方法。
//方法1:在main函数的最前面加上下面这句 5.6版本才开始有这个函数
#if (QT_VERSION > QT_VERSION_CHECK(5,6,0))
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
//方法2:在可执行文件同目录下新建文件 qt.conf 填入下面内容
[Platforms]
WindowsArguments = dpiawareness=0
//方法3:在main函数最前面设置Qt内部的环境变量
qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", "1.5");
//方法4:新版本的Qt比如Qt5.14修正了对高分屏的处理支持不是整数的缩放
qputenv("QT_ENABLE_HIGHDPI_SCALING", "1");
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
- QTabWidget选项卡有个自动生成按钮切换选项卡的机制,有时候不想看到这个烦人的切换按钮,可以设置usesScrollButtons为假,其实QTabWidget的usesScrollButtons属性最终是应用到QTabWidget的QTabBar对象上,所以只要设置全局的QTabBar的这个属性关闭即可。为啥要设置全局的呢,因为如果只是对QTabWidget设置了该属性,而在QMainWindow窗体中QDockWidget合并自动形成的选项卡只有QTabBar对象导致依然是有切换按钮。
//对tabWidget设置无切换按钮
ui->tabWidget->setUsesScrollButtons(false);
//对tabBar设置无切换按钮
ui->tabWidget->tabBar()->setUsesScrollButtons(false);
//对整个系统的选项卡设置无切换按钮
QTabBar{qproperty-usesScrollButtons:false;}
//设置选项卡自动拉伸 这玩意居然之前自动计算来设置原来内置了哇咔咔
QTabBar{qproperty-expanding:false;}
//设置选项卡关闭按钮可见
QTabBar{qproperty-tabsClosable:true;}
//还有其他属性参见QTabBar头文件有惊喜
//依旧是万能大法所有可视化类的 Q_PROPERTY 包含的属性都可以这样设置
- QMainWindow的分割线默认尺寸比较大,有时候想设置小一点或者不想要,最开始的时候以为是QSplitter,打印所有子元素找遍了也没找到影子,最后发现样式表中有对应设置的内容。
//真的是做梦也没想到要这样设置
QMainWindow::separator{width:1px;height:1px;margin:1px;padding:1px;background:#FF0000;}
Qt开发经验开源主页(持续更新):
Qt开发经验小技巧131-140的更多相关文章
- Qt开发经验小技巧81-90
Qt中的QColor对颜色封装的很完美,支持各种转换,比如rgb.hsb.cmy.hsl,对应的是toRgb.toHsv.toCmyk.toHsl,还支持透明度设置,颜色值还能转成16进制格式显示. ...
- Qt开发经验小技巧61-70
很多人问Qt嵌入式平台用哪个好,这里统一回答(当前时间节点2018年):imx6+335x比较稳定,性能高就用RK3288 RK3399,便宜的话就用全志H3,玩一玩可以用树莓派香橙派. 对于大段的注 ...
- Qt开发经验小技巧41-50
如果使用sqlite数据库不想产生数据库文件,可以创建内存数据库. QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); ...
- Qt开发经验小技巧71-80
在我们使用QList.QStringList.QByteArray等链表或者数组的过程中,如果只需要取值,而不是赋值,强烈建议使用 at() 取值而不是 [] 操作符,在官方书籍<C++ GUI ...
- Qt开发经验小技巧51-60
在某些http post数据的时候,如果采用的是&字符串连接的数据发送,中文解析乱码的话,需要将中文进行URL转码. QString content = "测试中文"; Q ...
- Qt开发经验小技巧31-40
代码判断MSVC编译器版本. if (_MSC_VER == 1800) MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015) MSVC++ 12.0 _ ...
- Qt开发经验小技巧21-30
如果出现Z-order assignment: is not a valid widget.错误提示,用记事本打开对应的ui文件,找到为空的地方,删除即可. 善于利用QComboBox的addItem ...
- Qt开发经验小技巧11-20
获取类的属性 const QMetaObject *metaobject = object->metaObject(); int count = metaobject->propertyC ...
- Qt开发经验小技巧1-10
当编译发现大量错误的时候,从第一个看起,一个一个的解决,不要急着去看下一个错误,往往后面的错误都是由于前面的错误引起的,第一个解决后很可能都解决了. 定时器是个好东西,学会好使用它,有时候用QTime ...
- Qt开发经验小技巧合集
一.开发经验总结 当编译发现大量错误的时候,从第一个看起,一个一个的解决,不要急着去看下一个错误,往往后面的错误都是由于前面的错误引起的,第一个解决后很可能都解决了. 定时器是个好东西,学会好使用它, ...
随机推荐
- kotlin集合——>集合概述、构造集合
1.kotlin集合概述 在kotli.collections包中包含List(有序集合).Set(无序集合).Map(健值对)三种集合 2.val定义的集合,调用集合方法可以添加删除,但是如果重新创 ...
- 我被 .NET8 JIT 的一个BUG反复折磨了半年之久
很久很久没有写过博客了, 正好最近园子又挣得一线生机, 必须得凑个热闹水一篇. 事情是这样的, 在今年的早些时候, 把公司的一部分api服务器的.net版本从6升级到了8, 毕竟6马上就是EOL了(. ...
- python项目实战——人生重开模拟器
文章目录 1.菜单栏的编写 2.玩家确定颜值.体质.智力.家境 3.生成性别 4.设定角色出生点 5.各个年龄段的变化 5.1 幼年阶段 5.2 青年阶段 5.3中年阶段 5.4 晚年阶段 6.整体代 ...
- 我用Replicate训练了个纹身Flux AI LORA模型,分享下经验
# 我用Replicate训练了个纹身AI模型,分享下经验 ## 起因 最近一直在研究AI辅助设计,正好我对纹身设计特别感兴趣.经过一段时间摸索,用Replicate平台训练了一个还不错的纹身设计模型 ...
- Clickhouse副本及分片
副本 副本的目的主要是保障数据的高可用性,即使一台 ClickHouse 节点宕机,那么也可以从其他服务器获得相同的数据 配置副本 1. zookeeper集群准备 2. Clickhouse准备两个 ...
- 题解:CF1776L Controllers
CF1776L Controllers 题解 分析 先把题目形式化.设 \(n\) 次加减中有 \(x\) 个加,\(y\) 个减,其中 \(a\) 加了 \(u\) 次,减了 \(v\) 次,显然 ...
- 【一步步开发AI运动小程序】十三、自定义一个运动分析器,实现计时计数02
随着人工智能技术的不断发展,阿里体育等IT大厂,推出的"乐动力"."天天跳绳"AI运动APP,让云上运动会.线上运动会.健身打卡.AI体育指导等概念空前火热.那 ...
- golang 判断文件或文件夹是否存在
//判断文件是否存在 存在返回 true 不存在返回false func checkFileIsExist(filename string) bool { var exist = true if _, ...
- dotnet学习笔记-专题06-过滤器和中间件-01
1. 基本概念 在ASP.NET Core中,中间件和过滤器都是处理HTTP请求的重要组件,但它们在应用中的位置.作用范围以及使用方式有所不同. 1.1 中间件和过滤器的区别 1.1.1 中间件 位置 ...
- .NET9 - Swagger平替Scalar详解(四)
书接上回,上一章介绍了Swagger代替品Scalar,在使用中遇到不少问题,今天单独分享一下之前Swagger中常用的功能如何在Scalar中使用. 下面我们将围绕文档版本说明.接口分类.接口描述. ...