当前位置: 首页 > ops >正文

Qt Core 之 QString

QString

    • 一、 为什么是 QString?
    • 二、 创建与初始化
      • 常用:
      • **补充:**
    • 三、 常用操作与成员函数
      • 1. 字符串拼接
      • 2. 字符串查询 与 判断
      • 3. 字符串修改 与 截取
      • 4. 字符串分割 与 列表拼接成字符串
      • 5. 数字与字符串的转换
    • 四、 与其他字符串类型的转换
    • 五、 场景应用与实践
    • 六、 注意点

QString 是 Qt 框架中用于处理字符串的核心类,在 Qt 开发中,涉及到与 Qt 的库交互时,使用 QString,往往会比标准库的 std::string更方便些。

Tips:使用 utf-8 编码格式,可以规避中文乱码的情况。

一、 为什么是 QString?

在 C++ 中,处理字符串通常使用 std::string(或更古老的 char*)。Qt 提供了 QString,并非重复造轮子,而是为了解决一些关键问题:

  1. Unicode 支持QString 内部使用 UTF-16 编码,这意味着它可以无缝地存储和显示世界上几乎所有书写系统的字符(如英文、中文、阿拉伯文、表情符号 😊)。这是它与 std::string(本质是字节数组)最根本的区别。
  2. 隐式共享(写时复制)QString 使用了隐式共享技术来优化内存和性能。多个 QString 对象可以共享同一份字符串数据,只有在某个对象需要修改数据时,才会真正执行复制操作。这对传递大型字符串非常高效。
  3. 丰富的 APIQString 提供了大量便捷的成员函数,用于字符串拼接、分割、查找、替换、大小写转换等操作,大大简化了字符串处理。
  4. 与 Qt 框架的无缝集成:几乎所有 Qt 的 API 都接受和返回 QString,这使得它在 Qt 生态中是无可替代的。
  5. 编码转换: 内置多种编码转换功能。

简单来说:在 Qt 项目中,应该始终使用 QString 而不是 std::string 来处理用户可见的文本。


二、 创建与初始化

QString 有多种创建方式,使用前需要#include <QString>
通常使用 构造函数 初始化字符串。

常用:

#include <QString>
#include <QDebug>int main(){// 1. 仅声明QString Str;// 方式一:调用构造函数QString qstr1 = QString("Hello from C-string");// 方式二:隐式调用构造函数(常见,有微小的开销)QString qstr2 = "Hello from C-string";return 0;
}

方法二中,编译器会在背后悄悄地调用了 QString(const char*) 这个构造函数,创建一个临时的 QString对象,然后再通过拷贝构造函数初始化 qstr,因此会有一点点开销。

补充:

#include <QString>
#include <QDebug>int main(){// 1. 空字符串QString emptyStr;// 2. 隐式调用构造函数,类似于C风格的字符串(const char*)构造// Qt会自动将const char*从本地编码转换为UTF-16。// Tips:在源文件中直接写中文等非ASCII字符,需确保文件编码为UTF-8(推荐)。QString str1 = "Hello, 世界!";// 3. 从另一个QString构造(拷贝构造,受益于隐式共享,开销很小)QString str2 = str1;// 4. 重复一个字符QString str3(5, 'Q'); // "QQQQQ"// 5. 使用 QStringLiteral 宏(推荐用于编译期字符串常量)// 此宏在编译期将字符串字面量直接转换为QString的内部格式,避免运行时的转换开销,性能最佳。QString str4 = QStringLiteral("性能更好的字符串常量");// 6. 使用 u"" 字面量(C++11及以上)// 这是另一种高效的初始化方式,直接从Unicode字面量创建QString。QString str5 = u"Unicode字符串";return 0;
}

三、 常用操作与成员函数

1. 字符串拼接

支持以下语法:

  • +运算符
  • append() 函数:追加
  • arg() 函数:格式化拼接。 ✅推荐
  • sprintf() 函数:格式化

为什么推荐方法三:

  1. 类型安全:在编译时由编译器检查参数类型是否正确,杜绝了因类型不匹配导致的运行时崩溃。
  2. 多语种翻译的支持:通过编号占位符(%1, %2)而非顺序占位符,让翻译人员能根据目标语言的语法灵活调整句子结构,实现地道的本地化,无需程序员修改代码。

    简而言之,有利于翻译达到“信达雅”中的“达”,读起来不拗口。

具体用法案例:

#include <QString>
#include <QDebug>QString str1 = "Hello";
QString str2 = "World";int main(){// 方法1:使用 `+` 运算符QString result1 = str1 + " " + str2 + "!";// 方法2:使用 `append()` 函数(会修改原对象)str1.append(" ").append(str2).append("!");// 方法3:使用 `arg()` 函数(格式化拼接,推荐)// %1, %2 是占位符,会被后面的参数按顺序替换。QString name = "Alice";int age = 25;QString message = QString("Name: %1, Age: %2").arg(name).arg(age);// message = "Name: Alice, Age: 25"// 方法4:使用sprintf(不推荐,Qt5后建议使用arg)QString msg;msg.sprintf("Score: %d, Ratio: %.2f", 100, 0.95);return 0;
}

2. 字符串查询 与 判断

常用功能:

  • 获取长度
  • 是否空字符串
  • 子串检查
  • 子串开头或结束
  • 查找子串位置
  • 比较字符串是否相等
#include <QString>
#include <QDebug>QString s = "Hello Qt";int main(){// 获取长度int len = s.length(); // or s.size(), s.count()// 是否为空/为空字符串bool isEmpty = s.isEmpty();bool isNull = s.isNull(); // 注意:isEmpty返回true不一定isNull返回true// 判断是否包含子串bool hasQt = s.contains("Qt"); // truebool hasQtCase = s.contains("qt", Qt::CaseInsensitive); // true, 大小写不敏感// 判断是否以某子串开始/结束bool starts = s.startsWith("Hello"); // truebool ends = s.endsWith("World"); // false// 查找子串位置int index = s.indexOf("l"); // 2, 第一个'l'的位置int lastIndex = s.lastIndexOf("l"); // 3, 最后一个'l'的位置// 比较int cmp = s.compare("hello qt", Qt::CaseInsensitive); // 0,表示相等bool eq = (s == "Hello Qt"); // truereturn 0;
}

3. 字符串修改 与 截取

常用功能:

  • 替换子串
  • 去除空白
  • 大小写转换
  • 插入与删除
  • 截取子串:可配合 查找字串位置*IndexOf函数 一起使用。

具体用法案例:

#include <QString>
#include <QDebug>QString s = "I like apples";
int main(){// 替换s.replace("apples", "oranges"); // "I like oranges"// 去除首尾空白字符(非常常用,处理用户输入)QString userInput = "  hello  \n";QString trimmed = userInput.trimmed(); // "hello" (不修改原对象)// userInput.trim(); // 这会修改原对象本身// 改变大小写QString lower = s.toLower(); // "i like apples"QString upper = s.toUpper(); // "I LIKE APPLES"// 插入与删除s.insert(2, "really "); // "I really like apples"s.remove(2, 7); // 从索引2开始删除7个字符 -> "I like apples"// 截取子串QString sub1 = s.mid(2); // "like apples" (从索引2到结尾)QString sub2 = s.mid(2, 4); // "like" (从索引2开始,截取4个字符)QString left = s.left(5); // "I lik"QString right = s.right(6); // "apples"return 0;
}

4. 字符串分割 与 列表拼接成字符串

常用功能:

  • 字符串的分割:返回给 QStringList对象。
  • 字符串列表的拼接:将字符串列表中的元素拼接成字符串。

具体用法案例:

#include <QString>
#include <QDebug>QString path = "usr/local/bin";int main(){// 分割:字符串 -> QStringListQStringList list = path.split('/');// list: ["usr", "local", "bin"]// 拼接:QStringList -> 字符串QString newPath = list.join('\\');// newPath: "usr\\local\\bin"return 0;
}

5. 数字与字符串的转换

QString 配备了数字与QString之间的转换函数。

#include <QString>
#include <QDebug>
int main(){// 数字 -> QStringQString s1 = QString::number(42); // "42"QString s2 = QString::number(3.14, 'f', 2); // "3.14" (格式'f', 精度2位)// QString -> 数字bool ok;int i = s1.toInt(&ok); // i=42, ok=truedouble d = s2.toDouble(&ok); // d=3.14, ok=truefloat f = s2.toFloat(&ok);// 如果转换失败,ok会被设为false,数字值设为0int bad = QString("hello").toInt(&ok); // bad=0, ok=falsereturn 0;
}

四、 与其他字符串类型的转换

其他的常见需求,主要包括:

  • QStringstd::string 之间
  • QByteArrayQString 之间

推荐规范示例:

#include <QString>
#include <QDebug>
int main(){QString qstr = "Hello, Qt";// 1. QString -> std::string// 注意:toStdString() 返回 UTF-8 编码的 std::string。std::string std_str = qstr.toStdString();// 2. std::string -> QStringQString from_std = QString::fromStdString(std_str);// 3. QString -> const char* (QByteArray)// 注意:toUtf8() 返回一个临时的 QByteArray 对象。// 不要保存这个data()指针,它的生命周期只在当前行!const char* c_str = qstr.toUtf8().constData(); // 正确用法:立即使用QByteArray byteArray = qstr.toUtf8(); // 如果需要持久化,保存QByteArrayconst char* persistent_c_str = byteArray.constData();// 4. const char* -> QStringQString from_c_str = QString::fromUtf8(c_str);// 5. QString -> 平台相关的本地编码 (Local 8-bit),依赖操作系统// 通常不推荐,除非与某些老旧的本地API交互。QByteArray localBytes = qstr.toLocal8Bit();// 6. 平台相关的本地编码 -> QStringQString from_local = QString::fromLocal8Bit(localBytes);return 0;
}

五、 场景应用与实践

应用场景:

  1. 处理用户界面文本:所有 QLabelQPushButton 等控件设置的文本都应使用 QString
  2. 文件路径操作QFile, QDir 等类都使用 QString 表示路径,完美支持中文等 Unicode 路径名。
  3. 网络数据接收:从网络接收的 UTF-8/UTF-16 数据,可以方便地用 QString::fromUtf8() 等进行转换。
  4. 拼接复杂消息:使用 arg() 方法进行格式化,易于阅读和后续的国际化翻译。
  5. 处理用户输入:使用 trimmed() 去除用户输入的首尾空白字符。

最佳实践

  • 性能:对于编译期的字符串常量,优先使用 QStringLiteral("text")
  • 编码:确保你的源代码文件保存为 UTF-8 编码,以避免中文乱码问题。
  • 转换:与 C 库或系统 API 交互时,注意使用 toUtf8()toLocal8Bit() 进行正确的编码转换,并注意指针的生命周期。
  • 隐式共享:放心地以值传递方式返回或传递 QString,隐式共享机制保证了其高性能。

六、 注意点

  1. constData() 指针的生命周期
    // 错误!temp对象在这一行结束后就被销毁,c_str成了悬空指针!
    const char* c_str = myQString.toUtf8().constData();// 正确!先将QByteArray保存到一个变量,延长其生命周期。
    QByteArray ba = myQString.toUtf8();
    const char* safe_c_str = ba.constData();
    
  2. “空”与“null”的区别
    • 默认构造的 QString() 既是 null 也是 empty
    • QString("")empty 但不是 null
    • 在大多数情况下,你应该使用 isEmpty() 来判断字符串是否有效。
  3. 跨线程操作QString可重入(Reentrant) 的,但不是线程安全(Thread-safe) 的。多个线程同时修改同一个 QString 对象需要外部同步机制(如互斥锁)。

持续更新中。。。。。。。

http://www.xdnf.cn/news/19293.html

相关文章:

  • PyTorch 张量(Tensor)详解:从基础到实战
  • 【深度学习】配分函数:近似最大似然与替代准则
  • python复杂代码如何让ide自动推导提示内容
  • 编写Linux下usb设备驱动方法:disconnect函数中要完成的任务
  • More Effective C++ 条款20:协助完成返回值优化(Facilitate the Return Value Optimization)
  • 每日算法题【栈和队列】:栈和队列的实现、有效的括号、设计循环队列
  • [软考中级]嵌入式系统设计师—考核内容分析
  • Redis持久化之AOF(Append Only File)
  • Java基础知识(十二)
  • 8.31【Q】CXL-DMSim:
  • vue3+vite+ts 发布npm 组件包
  • Deep Think with Confidence:llm如何进行高效率COT推理优化
  • 第24章学习笔记|用正则表达式解析文本文件(PowerShell 实战)
  • zkML-JOLT——更快的ZK隐私机器学习:Sumcheck +Lookup
  • Pytest 插件介绍和开发
  • leetcode 260 只出现一次的数字III
  • COLA:大型语言模型高效微调的革命性框架
  • 免费电脑文件夹加密软件
  • 基于Adaboost集成学习与SHAP可解释性分析的分类预测
  • 【K8s】整体认识K8s之存储--volume
  • 在win服务器部署vue+springboot + Maven前端后端流程详解,含ip端口讲解
  • Transformer架构三大核心:位置编码(PE)、前馈网络(FFN)和多头注意力(MHA)。
  • 学习Python中Selenium模块的基本用法(12:操作Cookie)
  • TFS-2005《A Possibilistic Fuzzy c-Means Clustering Algorithm》
  • 使用 Python 自动化检查矢量面数据的拓扑错误(含导出/删除选项)
  • 算法题(196):最大异或对
  • 特殊符号在Html中的代码及常用标签格式的记录
  • Qt组件布局的经验
  • 线程池、锁策略
  • 机器视觉opencv教程(四):图像颜色识别与颜色替换