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_LIB
qDebug() << "multimedia module is enabled";
#else
qDebug() << "multimedia module is not enabled";
#endif

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

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

Qt开发经验小技巧271-275的更多相关文章

  1. Qt开发经验小技巧81-90

    Qt中的QColor对颜色封装的很完美,支持各种转换,比如rgb.hsb.cmy.hsl,对应的是toRgb.toHsv.toCmyk.toHsl,还支持透明度设置,颜色值还能转成16进制格式显示. ...

  2. Qt开发经验小技巧61-70

    很多人问Qt嵌入式平台用哪个好,这里统一回答(当前时间节点2018年):imx6+335x比较稳定,性能高就用RK3288 RK3399,便宜的话就用全志H3,玩一玩可以用树莓派香橙派. 对于大段的注 ...

  3. Qt开发经验小技巧41-50

    如果使用sqlite数据库不想产生数据库文件,可以创建内存数据库. QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); ...

  4. Qt开发经验小技巧71-80

    在我们使用QList.QStringList.QByteArray等链表或者数组的过程中,如果只需要取值,而不是赋值,强烈建议使用 at() 取值而不是 [] 操作符,在官方书籍<C++ GUI ...

  5. Qt开发经验小技巧51-60

    在某些http post数据的时候,如果采用的是&字符串连接的数据发送,中文解析乱码的话,需要将中文进行URL转码. QString content = "测试中文"; Q ...

  6. Qt开发经验小技巧31-40

    代码判断MSVC编译器版本. if (_MSC_VER == 1800) MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015) MSVC++ 12.0 _ ...

  7. Qt开发经验小技巧21-30

    如果出现Z-order assignment: is not a valid widget.错误提示,用记事本打开对应的ui文件,找到为空的地方,删除即可. 善于利用QComboBox的addItem ...

  8. Qt开发经验小技巧11-20

    获取类的属性 const QMetaObject *metaobject = object->metaObject(); int count = metaobject->propertyC ...

  9. Qt开发经验小技巧1-10

    当编译发现大量错误的时候,从第一个看起,一个一个的解决,不要急着去看下一个错误,往往后面的错误都是由于前面的错误引起的,第一个解决后很可能都解决了. 定时器是个好东西,学会好使用它,有时候用QTime ...

  10. Qt开发经验小技巧合集

    一.开发经验总结 当编译发现大量错误的时候,从第一个看起,一个一个的解决,不要急着去看下一个错误,往往后面的错误都是由于前面的错误引起的,第一个解决后很可能都解决了. 定时器是个好东西,学会好使用它, ...

随机推荐

  1. .NET云原生应用实践(二):Sticker微服务RESTful API的实现

    本章目标 完成数据访问层的基本设计 实现Sticker微服务的RESTful API 引言:应该使用ORM框架吗? 毋庸置疑,Sticker微服务需要访问数据库来管理"贴纸"(也就 ...

  2. KubeSphere 镜像构建器(S2I)服务证书过期解决方案

    目前 KubeSphere 所有 3.x.x 版本,如果开启了 DevOps 模块并使用了镜像构建器功能(S2I)都会遇到证书过期问题. 解决方法 已开启 DevOps 模块 下载这个更新 S2I 服 ...

  3. python+ffmpeg视频转码转格式

    本文转发来自:https://blog.csdn.net/KH_FC/article/details/115771126 废话 python目前自己也是在学习当中,对python也不是特别精通,写视频 ...

  4. 乐观锁CAS

    在 Java 中,我们可以使用 synchronized 关键字和 CAS 来实现加锁效果. 悲观锁: 对于悲观锁来说,它总是认为每次访问共享资源时会发生冲突,所以必须对每次数据操作加上锁,以保证临界 ...

  5. Web渗透06_XSS

    XSS漏洞描述 XSS是非常厉害的漏洞,在OWASP TOP10中榜上有名. XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网 ...

  6. AOT漫谈专题(第七篇): 聊一聊给C#打造的节点依赖图

    一:背景 1. 讲故事 上一篇我们聊过AOT编程中可能会遇到的三大件问题,而这三大件问题又是考验你对AOT中节点图的理解,它是一切的原点,接下来我就画几张图以个人的角度来解读下吧,不一定对. 二:理解 ...

  7. 蚂蚁KAG框架核心功能研读

    作者介绍: 薛明:拥有近10年在医疗和零售领域应用机器学习和人工智能的经验.曾就职于通用电气.复星医药等企业.长期专注于医学图像.自然语言处理以及数据科学的研发工作,如训练/推理框架.数据挖掘与分析等 ...

  8. Flink Time

    基础概念 支持三种时间概念: Processing Time 时间递增 Ingestion Time : 摄入时间,数据进入Flink框架的时间,在Source Operator中设置,每个事件拿到当 ...

  9. 解密prompt系列42. LLM通往动态复杂思维链之路

    最近大家都在探讨和尝试复现OpenAI O1的思考效果,解码出的关键技术方向,包括之前已经探讨过的Inference Time Scaling在推理过程中进行路径决策和选择.但想要更优的Inferen ...

  10. docker部署java项目

    1.首先你需要提前准备好jar包或者war包,并想办法放入Linux环境(或虚拟机)中: 2.java项目的部署需要用到Tomcat或者Jetty,docker可以直接拉取他俩的镜像,这里以Tomca ...