1.类的快速调用
#pragma once
#include <QObject>
#ifndef RIW
#define RIW RulerInfoWrap::Instance()
#endif
class RulerInfoWrap : public QObject {
Q_OBJECT
public:
static RulerInfoWrap* Instance();
public:
RulerInfoWrap(QObject* parent = nullptr);
~RulerInfoWrap();
public:
void init();
};
//.cpp文件
#include "RulerInfoWrap.h"
#include <QDebug>
RulerInfoWrap* RulerInfoWrap::Instance()
{
qDebug() << "RulerInfoWrap::Instance()";
static RulerInfoWrap* ruler = new RulerInfoWrap();
return ruler;
}
RulerInfoWrap::RulerInfoWrap(QObject* parent)
: QObject(parent)
{
qDebug() << "RulerInfoWrap::RulerInfoWrap()";
}
RulerInfoWrap::~RulerInfoWrap()
{
qDebug() << "RulerInfoWrap::~RulerInfoWrap()";
}
void RulerInfoWrap::init()
{
qDebug() << "RulerInfoWrap::init()";
}
在其他文件中调用时只需要引用其头文件#include "RulerInfoWrap.h"然后
RIW->init();
delete RIW;
//打印如下:
RulerInfoWrap::Instance()
RulerInfoWrap::RulerInfoWrap()
RulerInfoWrap::init()
RulerInfoWrap::Instance()
RulerInfoWrap::~RulerInfoWrap()
2.创建目录
获取当前工作目录的路径:
QString path = QDir::currentPath() + "/config/serial_port.json";
QFileInfo fileInfo(path);
QDir dir = fileInfo.dir();
if (!dir.exists()) {
dir.mkpath(dir.absolutePath());
}
这段代码的功能是:给定一个文件路径,检查该文件所在的目录是否存在。
如果不存在,则创建这个目录及其所有必要的父目录。
这在确保文件可以被保存到一个预期的目录结构中时非常有用,
尤其是在应用程序需要自动管理其数据存储目录时。
QFileInfo fileInfo(path);
这行代码创建了一个QFileInfo对象,名为fileInfo。
QFileInfo类提供了关于文件的信息,比如文件的大小、创建时间、修改时间等。
这里,它被用来获取与给定路径path相关联的文件的信息
QDir dir = fileInfo.dir();
这行代码从fileInfo对象中获取文件所在的目录,并创建了一个QDir对象dir。
QDir类用于操作目录和目录路径,提供了创建、删除、重命名目录以及列出目录内容等功能。
fileInfo.dir()返回的是文件所在目录的QDir对象。
if (!dir.exists())
这行代码检查由fileInfo.dir()返回的目录是否存在。
dir.mkpath(dir.absolutePath());
如果目录不存在,这行代码将创建该目录。
dir.mkpath()是一个方法,用于创建由dir指定的路径,包括任何必要的父目录。
dir.absolutePath()返回dir对象的绝对路径,即完整的目录路径。
这意味着,如果dir是一个相对路径,mkpath会基于当前工作目录或绝对路径来创建整个目录结构。
3.json文件
3.1 写操作
将如下的Json字符串写入到文件中:
- 创建一个QJsonOBject对象,将各个键值对设置进QJsonOBject对象中
- 将QJsonOBject对象转换为QJsonDocument对象
- QJsonDocument对象在转换为QByteArry对象中。
- 通过文件操作写入到文件中
/* { "Name":"lisa", "Age":20, //Family中的value值是一个Json对象 "Family":{ "Father":"Gol·D·Roger", "Mother":"Portgas·D·Rouge", "Brother":["Sabo", "Monkey D. Luffy"] }, "IsAlive":false, "Comment":"yyds" } */ void qjson_write() { QJsonObject value; value.insert("Name","lisa"); value.insert("age",20); /* 封装: "Family":{ "Father":"Gol·D·Roger", "Mother":"Portgas·D·Rouge", "Brother":["Sabo", "Monkey D. Luffy"] } */ QJsonObject family_value; family_value.insert("Father","Gol·D·Roger"); family_value.insert("Mother","Portgas·D·Rouge"); QJsonArray bro_arry; bro_arry.push_back(QJsonValue("Sabo")); bro_arry.push_back(QJsonValue("Monkey D. Luffy")); family_value.insert("Brother",bro_arry); value.insert("Family",family_value); value.insert("IsAlive",false); value.insert("Comment","yyds"); QJsonDocument document(value); QByteArray s=document.toJson(); QFile file("E:\\test1.json"); file.open(QFile::WriteOnly); file.write(s); file.close(); }
bool Utils::WriteJsonFile(QString path, QJsonObject json) { // 写入Json文件到指定路径,路径不存在则创建 QFileInfo fileInfo(path); QDir dir = fileInfo.dir(); if (!dir.exists()) { dir.mkpath(dir.absolutePath()); } QFile file(path); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { qWarning() << "打开:" << path << "失败"; return false; } QJsonDocument doc(json); file.write(doc.toJson()); return true; }
3.2 读操作
- 将上面的文件给读取到QJsonDocument,并转换为QJsonObject.
- 将其中键值为 age,Name 和 Comment的进行打印。
void qjson_read() { //打开文件,并读取Json字符串 QFile file("E:\\test1.json"); file.open(QFile::ReadOnly); QByteArray s=file.readAll(); file.close(); //将Json字符串转换为QJsonDocument对象 QJsonDocument document=QJsonDocument::fromJson(s); QJsonObject object; if(document.isObject()){ object=document.object(); } //获取所有的key值 QStringList keys=object.keys(); // qDebug()<<object.size(); //遍历QJsonObject中所有的键值对 for(int i=0;i<object.size();i++) { QString key=keys.at(i); QJsonValue value=object[key]; if(value.isDouble()) { int v=value.toInt(); qDebug()<<key<<v; } else if(value.isString()) { QString s=value.toString(); qDebug()<<key<<s; } } }
std::optional<QJsonObject> Utils::ReadJsonFile(QString path) { // 加载Json文件 QFile file(path); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qWarning() << "打开:" << path << "失败"; return { std::nullopt }; } QJsonParseError error; QJsonDocument doc = QJsonDocument::fromJson(file.readAll(), &error); if (doc.isNull()) { qWarning() << "Failed to create JSON doc." << error.errorString(); return { std::nullopt }; } return { doc.object() }; }
4.获取ui值转化
4.1ui.hz->currentData().value<QSerialPort::BaudRate>();
这行代码是在使用Qt框架进行编程时可能遇到的一种用法,特别是在处理与串行端口(
QSerialPort
)相关的UI组件时。下面是对这行代码的详细解释:
ui.hz
:
ui
通常是一个用户界面(UI)对象,它是在使用Qt Designer设计界面时自动生成的,或者通过手动编码创建。hz
可能是ui
对象中的一个成员,通常是一个下拉框(QComboBox
)、列表视图(QListView
)或其他可以选择项目的控件。currentData()
:
- 这个方法通常用于获取当前选中项的数据。在Qt中,像
QComboBox
这样的控件提供了currentData()
方法,用于返回与当前选中项相关联的数据。- 需要注意的是,
currentData()
返回的类型是QVariant
,这是Qt中一个非常通用的数据类型,可以存储各种不同类型的数据。value<QSerialPort::BaudRate>()
:
value<T>()
是QVariant
类的一个模板方法,用于将QVariant
转换为特定类型T
的值。- 在这个例子中,
T
是QSerialPort::BaudRate
,这是Qt中定义的一个枚举类型,表示串行端口的波特率(如9600、115200等)。- 因此,
value<QSerialPort::BaudRate>()
将QVariant
转换为QSerialPort::BaudRate
类型的值。综上所述,这行代码的作用是:从用户界面控件
ui.hz
中获取当前选中项的数据,并将其转换为QSerialPort::BaudRate
类型的值。这通常用于配置串行端口的通信参数,例如,用户可能从一个下拉框中选择所需的波特率,然后程序使用该波特率来配置串行端口。
5.单例模式
5.1代码
#pragma once
#include <QObject>
#include "Ruler.h"
#ifndef RIW
#define RIW RulerInfoWrap::Instance()
#endif
class RulerInfoWrap : public QObject {
Q_OBJECT
public:
static RulerInfoWrap* Instance();
private:
RulerInfoWrap(QObject* parent = nullptr);
~RulerInfoWrap();
};
#include "pch.h"
#include "RulerInfoWrap.h"
#include <QSqlField>
#include "QDataWrap.h"
#include "QtUtils.h"
RulerInfoWrap* RulerInfoWrap::Instance()
{
static RulerInfoWrap* ruler = new RulerInfoWrap();
return ruler;
}
RulerInfoWrap::RulerInfoWrap(QObject* parent)
: QObject(parent)
{
}
RulerInfoWrap::~RulerInfoWrap()
{
}
引用:
auto&& opt = RIW->addRuler(ruler);
5.2代码
class Printer
{
private:
//1.定义一个静态的 对象指针变量 保存唯一示例地址
static Printer *signlePrint;
public:
//2.提供一个方法,获取单例指针
static Printer*getSignlePrint(void)
{
return signlePrint;
}
private:
//3.防止 该类实例化其他对象 将构造函数全部私有
Printer();
~Printer();
public:
//功能函数
void printText(char*str){
cout<<"打印"<<str<<endl;
}
}
Printer *Printer::signlePrint=new Printer;
调用:
Printer*p1=Printer::getSignlePrint();
p1->printText("你好");
6. 将QList<QStringList>转换为std::vector<std::vector<std::string>>
QList<QStringList> rows;
QStringList row1;
row1 << "New"
<< "Row"
<< "Data";
rows.append(row1);
QStringList row2;
row2 << "New2"
<< "Row2"
<< "Data2";
rows.append(row2);
// 将QList<QStringList>转换为std::vector<std::vector<std::string>>
std::vector<std::vector<std::string>> rows_str;
for (auto& row : rows) {
std::vector<std::string> row_str;
for (auto& item : row) {
row_str.push_back(item.toStdString());
}
rows_str.push_back(row_str);
}
7.for循环
特性 for (auto row : rows)
for (auto& row : rows)
row
的类型值的副本(拷贝) 元素的引用 是否影响原始容器 不影响 会直接影响 适用场景 只需要读取值,或对副本操作 需要修改容器中的元素 性能开销 可能有拷贝开销,尤其是复杂对象 无拷贝开销,但需注意避免误修改
实际使用建议
- 如果只是读取或处理临时值,用
for (auto row : rows)
。- 如果需要修改容器中的元素,用
for (auto& row : rows)
。- 如果不需要修改元素但想避免拷贝开销,可以用
for (const auto& row : rows)
。
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> rows = {1, 2, 3, 4, 5};
for (auto row : rows) { // 值拷贝
row = row * 2; // 修改的是副本
}
// 输出 rows,检查是否被修改
for (const auto& r : rows) {
cout << r << " "; // 输出: 1 2 3 4 5
}
cout << endl;
return 0;
}
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> rows = {1, 2, 3, 4, 5};
for (auto& row : rows) { // 引用
row = row * 2; // 修改的是原始值
}
// 输出 rows,检查是否被修改
for (const auto& r : rows) {
cout << r << " "; // 输出: 2 4 6 8 10
}
cout << endl;
return 0;
}
基于迭代器的
for
循环for (auto it = rows.begin(); it != rows.end(); ++it) {
// 对 *it 进行操作
}
std::vector<int> rows = {1, 2, 3, 4};
for (auto it = rows.begin(); it != rows.end(); ++it) {
*it *= 2; // 通过迭代器访问并修改元素
}
// rows: {2, 4, 6, 8}
map
//基于 C++17 的结构化绑定(Structured Bindings)的范围 for 循环
for (const auto& [key, value] : map) {
// key 是键, value 是值
}
//解释:
//C++17 引入了结构化绑定,允许直接解构类似 std::pair 或 std::tuple 这样的复合类型。
//这种写法常用于遍历 std::map 或其他包含键值对的容器。
//const auto& [key, value] 表示解构出每个元素的键和值,并通过引用访问它们。
//使用场景:
//遍历键值对容器(如 std::map 或 std::unordered_map)
std::map<int, std::string> my_map = {{1, "one"}, {2, "two"}};
for (const auto& [key, value] : my_map) {
std::cout << "Key: " << key << ", Value: " << value << std::endl;
}
// 输出:
// Key: 1, Value: one
// Key: 2, Value: two
for (const auto& mayt : mymap) {
cout << mayt.first << " ";
cout << mayt.second << endl;
}
// 遍历map
for (std::map<int, std::string>::iterator it = mymap.begin(); it != mymap.end(); ++it) {
std::cout << it->first << ": " << it->second << std::endl;
}
for (auto it = mymap.begin(); it != mymap.end(); ++it) {
std::cout << it->first << ": " << it->second << std::endl;
}
for (auto it = level_left_date.cbegin(); it != level_left_date.cend(); ++it) {
qDebug() << "Key:" << it.key() << ", Value:" << it.value();
}