Qt开发经验小技巧271-275

news/2024/10/28 18:32:51/
  1. 编程的过程中经常遇到需要将QString转成char *或者const char *的情况,在转换成QByteArray后调用.data()或者.constData()函数进行转换,这里需要注意的是,如果转换类型是const char *尽管用data()不会出错,会给你自动转换,但是还是不建议,因为深拷贝了一份,理论上增加了内存开销,如果字符串长度小还好,一旦很长,这个开销挺大,这是个好的编程习惯。
//查阅代码得知data函数有两个重载
inline char *QByteArray::data()
{ detach(); return d->data(); }
inline const char *QByteArray::data() const
{ return d->data(); }
inline const char *QByteArray::constData() const
{ return d->data(); }QByteArray data = "abc";
//深拷贝
char *d1 = data.data();
//深拷贝
const char *d2 = data.data();
//浅拷贝
const char *d3 = data.constData();//深拷贝
test(data.data());
//浅拷贝
test(data.constData());
void test(const char *data)
{    
}//至于什么时候调用.data()会浅拷贝,酷码大佬说是当QByteArray被const修饰的时候
const QByteArray data;
//浅拷贝
const char *d = data.data();//酷码大佬补充:自Qt 5.7版本以来,引入了qAsConst函数,专用于无脑转换。
//这个函数实现了C++17标准中的std::as_const()函数的功能,将一个非常量的左值转为常量的左值。
//增加qAsConst函数是为了Qt自己的非const 的容器能实现C++11标准的基于范围的循环。
//该函数主要用于qt容器在隐式共享中不被detach。
QString s = "abc";
//下面会深拷贝引起性能损失
for (QChar ch : s)
//不会深拷贝
for (QChar ch : qAsConst(s))
//下面也是浅拷贝,但是在编程时、在现实中,声明为const往往不容易做到。
const QString s;
for (QChar ch : s)//总结:对Qt自己实现的容器如:QVector、QMap、 QHash、QLinkedList、QList等,如果一定要用基于for(var : container)范围的循环,则请用如下形式:
for (var : qAsConst(container))
  1. 新版的Qt6.5在ubuntu上编译运行程序后会提示 qt.qpa.plugin: Could not load the Qt platform plugin “xcb” in “” even though it was found. ,无法正常弹出窗体程序,你需要主动安装xcb的相关库。sudo apt install libxcb*

  2. 有些场景下我们需要在 QApplication a(argc, argv); 前面执行一些处理,比如 QApplication::setAttribute 就必须在最前面执行,而很多时候这个设置的参数不能改写死,毕竟现场的环境千差万别,希望通过配置文件来配置,那么问题来了,读取配置文件一般需要指定路径才能正常读取到,如果是 ./ 这种,很可能未必是应用程序的当前路径,如果你是双击运行的程序,那肯定是应用程序的当前路径,不是双击运行那就是系统环境中的当前路径,意味着你开机启动或者用system、QProcess等方式在开机后调用启动的话,就未必正确了。为了保证这个路径的正确,必须从main函数的 argv 第一个值获取,通过查阅Qt自身代码中获取路径,也是从这个参数获取。

//程序最前面获取应用程序路径和名称
static void getCurrentInfo(char *argv[], QString &path, QString &name);
//程序最前面读取配置文件节点的值
static QString getIniValue(const QString &fileName, const QString &key);
static QString getIniValue(char *argv[], const QString &key, const QString &dir = QString());void QUIHelper::getCurrentInfo(char *argv[], QString &path, QString &name)
{//必须用fromLocal8Bit保证中文路径正常QString argv0 = QString::fromLocal8Bit(argv[0]);QFileInfo file(argv0);path = file.path();name = file.baseName();
}QString QUIHelper::getIniValue(const QString &fileName, const QString &key)
{QString value;QFile file(fileName);if (file.open(QFile::ReadOnly | QFile::Text)) {while (!file.atEnd()) {QString line = file.readLine();if (line.startsWith(key)) {line = line.replace("\n", "");line = line.trimmed();value = line.split("=").last();break;}}}return value;
}QString QUIHelper::getIniValue(char *argv[], const QString &key, const QString &dir)
{QString path, name;QUIHelper::getCurrentInfo(argv, path, name);QString fileName = QString("%1/%2%3.ini").arg(path).arg(dir).arg(name);return getIniValue(fileName, key);
}int main(int argc, char *argv[])
{int openGLType = QUIHelper::getIniValue(argv, "OpenGLType").toInt();QUIHelper::initOpenGL(openGLType);QApplication a(argc, argv);...
}
  1. 当我们对QTableView/QTreeView/QTableWidget/QTreeWidget某行选中后,会发现某些单元格设置的前景色被覆盖了,比如设置的红色,一旦选中就变成了白色,这肯定不是我们想要的,需要用自定义委托将其去掉。
class ItemDelegate : public QItemDelegate
{Q_OBJECT
public:explicit ItemDelegate(QObject *parent = 0);protected:void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
};#include "itemdelegate.h"ItemDelegate::ItemDelegate(QObject *parent) : QItemDelegate(parent)
{}void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{QStyleOptionViewItem option2 = option;QColor color = index.data(Qt::ForegroundRole).value<QColor>();if (color.isValid() && color != option.palette.color(QPalette::WindowText)) {option2.palette.setColor(QPalette::HighlightedText, color);}QItemDelegate::paint(painter, option2, index);
}//对所有单元格设置该委托
ui->tableWidget->setItemDelegate(new ItemDelegate);
  1. 有些时候我们需要在项目文件比如pro/pri中识别当前Qt套件是否存在某个模块以及是否引入过某个模块,存在则引入,同时也希望代码中也能识别是否引入过某个模块比如sql模块,判断后再进行对应的处理。
//项目文件中判断
//如果当前套件中有multimedia模块则引入multimedia模块
qtHaveModule(multimedia) {QT += multimedia}
//在项目文件中已经通过 QT += multimedia 引入过模块
contains(QT, multimedia) {}//代码文件判断
#ifdef QT_MULTIMEDIA_LIBqDebug() << "multimedia module is enabled";
#elseqDebug() << "multimedia module is not enabled";
#endif

国内站点:https://gitee.com/feiyangqingyun
国际站点:https://github.com/feiyangqingyun


http://www.ppmy.cn/news/597917.html

相关文章

游戏平台代表--PS4【推荐】

目前市上专业的游戏主机三足鼎立&#xff0c;分别是任天堂的wii&#xff0c;微软的xbox&#xff0c;已经索尼的PlayStation系列&#xff0c;这其中的老大当然是索尼PS4啦&#xff0c;因为即使美国佬也是优选ps4而不是自家的Xbox。小编历经千辛万科终于购入了一台ps4&#xff08…

索尼游戏平台针对被黑事件补偿玩家

索尼PlayStation官方网站今日发布消息&#xff0c;针对圣诞节黑客攻击PlayStation Network服务器一事&#xff0c;对玩家作出补偿&#xff0c;决定向PS Plus会员提供额外5天会籍&#xff0c;及向所有PSN会员提供一组特惠代码以九折优惠购买PlayStation Store购物车中所有内容一…

NFT游戏有哪些?盘点当前热门的NFT游戏

全文导读 在了解NFT游戏有哪些之前&#xff0c;我们不妨先来了解一下NFT&#xff0c;很多币圈新手虽然经常听说NFT&#xff0c;但是还不知道这个NFT具体是什么。其实NFT的中文名是非同质化代币&#xff0c;它就是一个智能合约&#xff0c;相当于给某个数字资产独一无二的身份证…

在中国大陆,XGP对比Steam有什么优势?

6个月前&#xff0c;我入手了《Persona 5 Royal 女神异闻录5皇家版》&#xff08;简称P5R&#xff09;的PS4光盘&#xff0c;玩了一小段就搁置了&#xff0c;2022年10月21日&#xff0c;P5R登录了全平台&#xff0c;而PS4光盘又无法升级到PS5版&#xff0c;为了低价享受更好的画…

直流恒流源电路分析-运放恒流源设计

7种直流恒流源电路分析 传感器及发光器件常需恒流源供电&#xff0c;精确测量微小电阻一般也要用到恒流源。恒流源的本质是其具有调节负载两端电压的能力&#xff0c;凡具有电压调整能力的器件均可构成恒流源&#xff0c;包括运放、稳压芯片、三极管、MOS管等。下面以运放和电…

FPGA_学习_09_PWM呼吸灯

PWM在三相电机控制中&#xff0c;有着非常重要的地位。 如果你需要用FPGA去实现三相电机的控制&#xff0c; PWM这一关是绕不过的。好在PWM的基本原理是比较简单的。所以原理部分本文就略过&#xff0c;本文基于PWM实现呼吸灯。 1 时序 {signal: [{name: clk, wave: p....…

Acwing128. 编辑器

题目链接&#xff1a;128. 编辑器 - AcWing题库 标签&#xff1a;堆顶栈 思路&#xff1a;分别用两个栈&#xff0c;记录光标左边的数和光标右边的数&#xff1b;用s记录前缀和&#xff0c;f记录最大前缀。 对题目所示五个操作有&#xff1a; 1.插入操作&#xff1a;将x插入…

模板匹配Template Matching

实现代码&#xff1a; import cv2 import numpy as np def template_demo(tpl,target):methods[cv2.TM_SQDIFF_NORMED,cv2.TM_CCORR_NORMED,cv2.TM_CCOEFF_NORMED]th,twtpl.shape[:2]for md in methods:start_timecv2.getTickCount()# 匹配结果resultcv2.matchTemplate(target…