当前位置:首页>Linux>四,Linux C++/Qt 基础编程(二)Qt部分

四,Linux C++/Qt 基础编程(二)Qt部分

  • 2026-10-11 07:20:22
四,Linux C++/Qt 基础编程(二)Qt部分
Linux C++/Qt 基础编程内容较多,为方便阅读,Qt部分拆出来一章。
Qt Widget 和 Qt Quick 是 Qt 中两套完全不同的 UI 技术栈,设计目标、使用方式和适用场景都有明显差异。
如何选择?
下面我们将使用两种架构分别做两个项目。
其中可视化读取设置PWM值和TXT文本读写使用widget实现。JSON文件读取显示使用quick架构实现。
1,可视化风扇调试系统
创建空的widget项目:
创建完成
现在就可以将程序编译上传到开发板看一下效果,只是一个空白的窗体。
修改:
1,窗体大小与屏幕一致1280*720,并且全屏显示
2,添加标题“PWM控制系统”
编译上传看效果:
UI设计
代码设计:
首先添加定时器,500ms读取一次PWM值。
读取的方式,把C++中练习读PWM的代码抄过来。
在Timer定时回调函数中更新画面。
设定PWM控制转速的实现与C++一致,把代码抄过来。
然后在旋钮改变值的函数中调用这个函数,设置PWM。
编译上传,在屏幕滑动旋钮改变数值,查看log和风扇转速。
2,txt文本浏览器
        txt文本浏览器是把C++编程中的txt文件读写程序做成可视化软件的升级。软件框架继续使用widget。
        项目继续使用可视化PWM控制的工程,只是添加一个ui,由c++选择加载显示。
添加一个ui画面:
创建完成后是默认大小和样式。我们把它改成我们想要的样子。
然后处理打开文件动作:
再把在cpp_practice中读txt的代码拷贝过来:
编译上传开发板运行:
添加输入法,实现编辑保存。
1,添加输入法文件
2,导入输入法资源
3,启用输入法
4,准备一个txt文件。
我们使用ls命令把输出直接写入一个aaaa.txt文件
5,打开软件编辑aaaa.txt内容
6,点击保存后,到命令行中使用cat查看修改后的内容:
------------------------------------------------------------------------
      上面两个GUI程序都是widget架构,接下来读取显示JSON的程序我们将使用quick架构。
创建项目:最新的Qt Creator是基于Qt6的,我们用的是Qt5,所以要用旧版本的Qt Creator创建 quick项目以支持Qt5.
项目创建后,关闭这个旧版本的Qt Creator即可。然后到文件中删除配置。
然后用新版本的Qt Creator打开进行开发。
选择SDK 
QML也有可视化设计界面,但是几乎没人用,不如写代码实现。不信的自己试试,我就不陪你试了。
在QML界面程序开发当中,MVC架构格外明显。这里在设计页面之前先对MVC架构进行介绍。
这个项目中读取的JSON数据就是model,qml及加载qml的类属于view,model读取JSON数据传递给view进行更新显示,中间传话的就是controller。
作为一个中间人,他既要能够跟model部分进行C++交互,又要能够跟qml交互。我们有两种方式创建这样的一个角色,一是注册类,二是注册类型。而且这个注册动作必须在qml页面加载之前进行。
两种方法比较:

qmlRegisterType<T>() —— 把 C++ 类注册成 QML 里可实例化的类型,QML 侧能 MyType { … }随便 new。

qmlRegisterSingletonType<T>() —— 把 C++ 类注册成 QML 单例,全局唯一定义,QML 侧直接 MySingleton.xxx访问,不能 new。

先来演示qmlRegisterType
首先创建一个类,这个类必须继承QObject。
添加类后,在类中添加一个函数和一个信号。函数必须用Q_INVOKABLE
来修饰,这样QML中才能调用。而且这个函数必须在对应cpp中有实现。
这样的类才可以注册到QML环境中,下面在main.cpp中注册这个类的类型到QML上下文中。
这样注册类型后便可以在QML中使用,但是需要先import :
在QML中调用方法和接受信号,函数不在这里调用,只是演示:
再演示 qmlRegisterSingletonType 注册上下文句柄的方式
添加类的方式与qmlRegisterType相同。这个类起名:Singleton_js_ctl。
然后这个类需要特殊处理:
然后在main.cpp中使用qmlRegisterSingletonType 注册类型。
简单添加文件选择功能,页面布局美化不细说了。
文件选择使用我司提供的 MyFileDialog.qml 实现
运行效果
现在我们准备一个JSON文件,打开并格式化读取输出它。
我们让AI生成一个JSON,提示词:
写一个JSON文件,包含root节点,然后是people节点,每个people节点有身高体重性别属性。不要过度解释。
{  "root": {    "people": [      {        "height": 175,        "weight": 70,        "gender": "male"      },      {        "height": 165,        "weight": 55,        "gender": "female"      },      {        "height": 180,        "weight": 75,        "gender": "male"      }    ]  }}
上面是生成的JSON文件内容,我们把它保存到本地的一个JSON文件中:jsontest.json 。
然后继续问AI,让它帮们写一段格式化读json的程序
提示词:

然后再linux系统重使用C++语言和CJSON库读取这个JSON文件,把每个人的属性存在一个结构体当中,结构体存在vector当中。

在 Singleton_js_ctl 中添加一个 void readjson(QString path); 函数实现这个功能。
在cmakelists中添加cjson库
# 禁用cJSON的Config模式set(cjson_FOUND TRUE)# 手动设置set(CJSON_INCLUDE_DIRS     /qirou_tools/aarch64-linux-gnu_t527sdk/aarch64-buildroot-linux-gnu/sysroot/usr/include/cjson)set(CJSON_LIBRARIES    /qirou_tools/aarch64-linux-gnu_t527sdk/aarch64-buildroot-linux-gnu/sysroot/usr/lib/libcjson.so)include_directories(${CJSON_INCLUDE_DIRS})target_link_libraries(your_target_name ${CJSON_LIBRARIES})
读取json代码:
voidSingleton_js_ctl::readjson(QString path){    std::ifstream file(path.toLocal8Bit ().data ());    if (!file.is_open()) {        std::cerr << "Failed to open file" << path.toLocal8Bit ().data () << std::endl;        return;    }    std::string content((std::istreambuf_iterator<char>(file)),std::istreambuf_iterator<char>());    file.close();    cJSON *root = cJSON_Parse(content.c_str());    if (!root) {        std::cerr << "JSON parse error" << std::endl;        return;    }    cJSON *peopleArray = cJSON_GetObjectItem(root, "root");    peopleArray = cJSON_GetObjectItem(peopleArray, "people");    std::vector<Person> persons;    cJSON *item = nullptr;    cJSON_ArrayForEach(item, peopleArray) {        Person p;        cJSON *height = cJSON_GetObjectItem(item, "height");        cJSON *weight = cJSON_GetObjectItem(item, "weight");        cJSON *gender = cJSON_GetObjectItem(item, "gender");        p.height = height->valueint;        p.weight = weight->valueint;        strncpy(p.gender, gender->valuestring, sizeof(p.gender) - 1);        p.gender[sizeof(p.gender) - 1] = '\0';        persons.push_back(p);    }    cJSON_Delete(root);    // 验证输出    for (const auto &p : persons) {        std::cout << "Height: " << p.height                  << ", Weight: " << p.weight                  << ", Gender: " << p.gender << std::endl;    }}
main.qml中引入上下文类型
然后在选择文件后调用读取
QML接受ctroller信号,页面显示格式化读取的json内容。
运行效果:

最新文章

随机文章