Qt跨平台开发demo(适用萌新)

最近需要参与一款Qt跨平台的软件开发,在此之前,特把基础信息做学习和梳理,仅供参考。

所使用的技术和版本情况如下:

  • 虚拟机:VMware 16.2.5
  • 操作系统:ubuntu-20.04.6-desktop-amd64:
  • Mysql数据库 8.0.36
  • Workbench (mysql-workbench-community_8.0.29-1ubuntu20.04_amd64.deb)
  • QT 5.12.12(qt-opensource-linux-x64-5.12.12.run)

ps:有人问为什么不用VirtualBox、GNOME Boxes,或者其他Qt、mysql版本问题,前者是因为个人习惯,后者是因为项目要求。

1、开发环境搭建

参考这篇

2、MVC简介

MVC模式是软件工程中常见的一种软件架构模式,该模式把软件系统(项目)分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。

使用MVC模式有很多优势,例如:

  • 简化后期对项目的修改、扩展等维护操作;

  • 使项目的某一部分变得可以重复利用;使项目的结构更加直观。

具体来讲,MVC模式可以将项目划分为模型(M)、视图(V)和控制器(C)三个部分,并赋予各个部分不同的功能,方便开发人员进行分组。

**(1)模型(Model):**模型持有所有的数据、状态和程序逻辑。模型接受视图数据的请求,并返回最终的处理结果。

**(2)视图(View):**负责界面的显示,以及与用户的交互功能,例如表单、网页等。

**(3)控制器(Controller):**可以理解为一个分发器,用来决定对于视图发来的请求,需要用哪一个模型来处理,以及处理完后需要跳回到哪一个视图。即用来连接视图和模型。

实际开发中,通常用控制器对客户端的请求数据进行封装(如将form表单发来的若干个表单字段值,封装到一个实体对象中),然后调用某一个模型来处理此请求,最后再转发请求(或重定向)到视图(或另一个控制器)。

在这里插入图片描述

3、代码设计与实现

1、框架构成

一个基于C++和QML的跨平台项目框架通常包含以下几个主要组成部分:后端C++逻辑、QML前端界面、信号与槽机制进行通信,以及可能的数据存储(如数据库)。下面是对这个框架构成的简单描述:

1. 后端C++逻辑

  • C++类库:C++代码部分通常包含一系列类,这些类封装了应用程序的核心逻辑。这些类可能包括数据处理、算法实现、网络通信、文件操作等。
  • 数据库访问:持久化存储数据,C++代码需包含与数据库交互的逻辑。这通常涉及使用数据库API或ORM(对象关系映射)库来执行查询、插入、更新和删除操作。
  • 业务逻辑:C++代码包含应用程序的业务逻辑,即根据用户需求和数据状态执行的操作。

2. QML前端界面

  • QML文件:QML是一种用于描述用户界面的声明式语言,它类似于HTML和CSS的结合。QML文件定义了应用程序的外观和布局,包括窗口、按钮、文本框等界面元素。
  • 界面元素:QML文件中包含各种界面元素,这些元素通过属性和信号与C++代码进行交互。例如,一个按钮的点击事件可以触发一个信号,该信号被C++代码中的槽函数捕获并处理。
  • 样式和主题:QML还支持自定义样式和主题,以便轻松更改应用程序的外观。

3. 信号与槽机制进行通信

  • 信号:在Qt框架中,信号是对象在特定事件发生时发出的一种通知。QML界面元素和C++对象都可以发出信号。
  • :槽是响应信号的函数或方法。当信号被发出时,与之关联的槽函数将被调用。这种机制允许QML界面与C++后端逻辑进行无缝通信。
  • 连接信号与槽:在应用程序中,需要显式地将信号连接到槽。这可以在C++代码中完成,也可以在QML文件中使用Qt的内置函数(如Connections元素)完成。

4. 应用程序集成

  • 主函数:C++代码中的主函数(通常是main.cpp)负责初始化Qt应用程序,加载QML界面,并将它们与C++后端逻辑集成在一起。
  • 资源文件:为了管理应用程序中的资源(如QML文件、图像、字体等),你可以使用Qt的资源系统。资源文件(通常是.qrc文件)定义了这些资源的路径和属性。
  • 编译和部署:使用Qt的构建系统(如qmake或CMake)编译应用程序,并确保在目标平台上部署所有必要的依赖项和运行时库。

通过这种框架,你可以开发出既具有强大功能又具有良好用户体验的跨平台应用程序。C++后端提供了灵活性和性能,而QML前端则提供了直观和易于定制的用户界面。

如果是和我一样的QML小白,推荐看两个视频:

数据库相关操作,包含事务命令:UP:爱编程的大丙

QML教程(P20-23,QML与C++交互):UP:落雨薄青衫

2、代码部分

先贴库:gitee

1、.pro文件

Qt项目的.pro文件(也称为qmake项目文件)。这个文件用于描述如何构建Qt项目,并包含了编译项目所需的各种设置和指令。下面我将逐一解释这个文件中的各个部分:

这是一个Qt项目的.pro文件(也称为qmake项目文件)。这个文件用于描述如何构建Qt项目,并包含了编译项目所需的各种设置和指令。主要关注前面:

  1. QT += quick qml sql quickcontrols2

    指定了项目需要使用的Qt模块。这里指定了quick(用于Qt Quick框架),qml(QML支持),sql(数据库支持)和quickcontrols2(Qt Quick Controls 2 UI框架)。

  2. CONFIG += c++11

    指示qmake使用C++11标准来编译项目。

总的来说,这个.pro文件为Qt项目提供了构建和安装的详细信息。可以根据项目的具体需求来修改。

2、头文件

DbConnector主要处理数据库:

class DbConnector : public QObject
{Q_OBJECT
public:explicit DbConnector(QObject *parent = nullptr);~DbConnector();static DbConnector * getInstance();void createSql();	//用于初始化数据库(打开,连接),在构造函数内调用void closeSql();  //用于关闭数据库,在析构函数内调用Q_INVOKABLE QSqlDatabase getDb();
private:QSqlDatabase db;	//定义一个数据库变量
};

MyListModel主要处理自定义模型的数据:

class MyListModel : public QAbstractListModel
{Q_OBJECT
public:enum MyRoleName{Name = Qt::DisplayRole + 1,Value};explicit MyListModel(QObject *parent = nullptr);static MyListModel * getInstance();Q_INVOKABLE bool select();void refreshData();int rowCount(const QModelIndex &parent = QModelIndex()) const override;QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;QHash<int,QByteArray> roleNames() const override;Q_INVOKABLE void addData(QString s);Q_INVOKABLE void updateData(int id,QString s);Q_INVOKABLE void onEnterPressed(int id,QString s);public slots:void addSlot(QString s);void updateSlot(int id,QString s);void onEnterPressedSlot(int id,QString s);
private:QList<QString> m_data;
};

3、源文件

DbConnector:

数据库连接

void DbConnector::createSql()
{db = QSqlDatabase::addDatabase("QMYSQL");//mysql需要自己编译,没有的话查看我上篇的解决方案db.setHostName("localhost");//自己填db.setUserName("username");//自己填db.setDatabaseName("DatabaseName");//自己填db.setPassword("密码");//自己填db.setPort(3306);//自己查if(!db.open()){qDebug()<<"fail :"<<db.lastError().text();}else{qDebug()<<"open db success";}
}

添加逻辑:

void MyListModel::addSlot(QString s)
{addData(s);refreshData();
}
void MyListModel::addData(QString s)
{QSqlQuery query;QString sql = "INSERT INTO person (name) VALUES (:name)";// 使用prepare()方法来准备SQL语句,并使用bindValue()来绑定参数query.prepare(sql);query.bindValue(":name", s);// 执行SQL语句if (!query.exec()){qDebug() << "Failed to insert name:" << query.lastError().text();}else{qDebug() << "Successfully inserted name:" << s;}
}
void MyListModel::refreshData()
{beginResetModel(); // 视图模型更改if(select()){qDebug()<<"refresh data success";}else{qDebug()<<"refresh data failed";}endResetModel();
}

更新逻辑:

void MyListModel::updateSlot(int id,QString s)
{updateData(id,s);int row = id;// 通知QML该元素已更改emit dataChanged(index(row, 0), index(row, 0));refreshData();
}
void MyListModel::updateData(int id, QString s)
{id++;QSqlQuery query;QString sql = "UPDATE person SET name = :newName WHERE id = :id";// 使用prepare()方法来准备SQL语句,并使用bindValue()来绑定参数query.prepare(sql);query.bindValue(":newName", s);query.bindValue(":id", id);// 执行SQL语句if (!query.exec()){qDebug() << "Failed to update name for id:" << id << "Error:" << query.lastError().text();return;}qDebug() << "Successfully updated name for id:" << id;
}

4、QML文件

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12Window {id:windowwidth: 640height: 480visible: truetitle: qsTr("Hello World")//信号signal addSig(string s)signal updateSig(int id,string s)signal onEnterPressedSig(int id,string s)ComboBox{id:comboBoxx:10y:10z:1width:150height: 40model:MyListModelcurrentIndex: 0font.pointSize: 12editable: true //允许编辑delegate:ItemDelegate{id:delegatewidth:comboBox.widthheight: comboBox.heightcontentItem: Text{text:nameanchors.fill:parentcolor:"black"font:comboBox.fontelide:Text.ElideRightverticalAlignment: Text.AlignVCenter}highlighted: index === comboBox.highlightedIndex//悬浮}Component.onCompleted:{comboBox.editText = "请选择"addSig.connect(MyListModel.addSlot)updateSig.connect(MyListModel.updateSlot)onEnterPressedSig.connect(MyListModel.onEnterPressedSlot)}Button{x:50y:50id:btntext:"新增"onClicked:{var editText = comboBox.editText;addSig(editText);comboBox.currentIndex = MyListModel.rowCount()-1;console.log("currentIndex is ",comboBox.currentIndex);}}Button{x:50y:100id:btn2text:"修改"onClicked:{var currentIndex = comboBox.currentIndex-1;var editText = comboBox.editText;updateSig(currentIndex,editText);}}}
}

Button实现起来比较简单一点,也更符合正常的逻辑。
在这里插入图片描述

4、总结

整体项目不难,但是“五脏俱全”,包含了一个QT跨平台项目最基本的知识点,适合新人练手。
希望大神们多多批评指正,我也是刚上手。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3019042.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

机器人系统仿真

0、何为仿真 通过计算机对实体机器人系统进行模拟的技术。 1、为何仿真 低成本&#xff1a; 机器人实体一般价格昂贵&#xff0c;为降低机器人学习、调试的成本&#xff1b;高效&#xff1a; 搭建的环境更为多样且灵活&#xff0c;可以提高测试效率以及测试覆盖率&#xff1b…

MS86235运算放大器可Pin to Pin兼容OPA2835

MS8635/MS86235是一款低功耗的单/双通道低噪声、轨到轨输出、高速运算放大器&#xff0c;可由2.7V至5V范围内的单电源或者1.35V至2.5V范围内的双电源供电运行。可Pin to Pin兼容OPA2835。每通道仅消耗630μA的电流&#xff0c;单位增益带宽为66MHz&#xff0c;在节能模式下&…

从几个方面判断代理IP的质量?

代理IP的质量对于网络活动至关重要&#xff0c;它直接影响到用户的隐私保护、访问速度、稳定性以及整体的网络体验。以下是从几个关键方面来判断代理IP质量的详细分析&#xff1a; 第一点稳定性&#xff1a;稳定性是评估代理IP质量的首要因素。一个优质的代理IP应该具备高稳定…

LINUX 入门 8

LINUX 入门 8 day10 20240507 耗时&#xff1a;90min 有点到倦怠期了 课程链接地址 第8章 TCP服务器 1 TCP服务器的介绍 开始讲服务器端&#xff0c;之前是客户端DNShttps请求 基础&#xff1a;网络编程并发服务器&#xff1a;多客户端 一请求&#xff0c;一线程 veryold…

武汉星起航:亚马逊:跨境电商领军平台,中国卖家全球拓展的首选

2015年&#xff0c;亚马逊全球开店业务正式进入中国&#xff0c;为中国卖家带来了全新的跨境电商机遇。如今&#xff0c;亚马逊已在全球拥有包括美国、加拿大、墨西哥、英国、法国、德国等在内的17大海外站点&#xff0c;为中国卖家提供了广阔的销售市场。武汉星起航将详细探讨…

2024年北京服贸会媒体邀约资源有哪些?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 2024年北京服贸会&#xff08;中国国际服务贸易交易会&#xff0c;简称CIFTIS&#xff09;作为中国重要的国际性服务贸易盛会&#xff0c;会吸引众多媒体的关注和参与。媒体邀约资源通常…

Linux中每当执行‘mount’命令(或其他命令)时,自动激活执行脚本:输入密码,才可以执行mount

要实现这个功能&#xff0c;可以通过创建一个自定义的mount命令的包装器&#xff08;wrapper&#xff09;来完成。这个包装器脚本会首先提示用户输入密码&#xff0c;如果密码正确&#xff0c;则执行实际的mount命令。以下是创建这样一个包装器的步骤&#xff1a; 创建一个名为…

【强训笔记】day14

NO.1 思路&#xff1a;用一个哈希表&#xff0c;先遍历s1&#xff0c;统计哈希表内的字符个数&#xff0c;在遍历s2&#xff0c;s2中的字符在哈希表中减去&#xff0c;如果哈希表中的字符个数小于0那么就输出No。 代码实现&#xff1a; #include <iostream> #include&…

有没有国内个人可用的GPT平替?推荐5个AI工具

随着AI技术的快速发展&#xff0c;AI写作正成为创作的新风口。但是面对GPT-4这样的国际巨头&#xff0c;国内很多小伙伴往往望而却步&#xff0c;究其原因&#xff0c;就是它的使用门槛高&#xff0c;还有成本的考量。 不过&#xff0c;随着GPT技术的火热&#xff0c;国内也涌…

【Windows】VB项目运行报错Run-time error ‘339‘

【Windows】VB项目运行报错Run-time error 339 1.背景描述2.解决办法 1.背景描述 高压电源厂家用vb写了一个上位机软件&#xff0c;到用户windows计算机上运行后&#xff0c; 连接串口报错&#xff1a; Component MSCOMM32.OCX or one of its dependencies not correctly reg…

实现左上角的固定视口但是网格以图片中心放大缩小

仅仅修改了showbk&#xff08;&#xff09; 函数部分&#xff0c;增加bkv4 直接采样&#xff0c;然后粘贴到左上角&#xff0c;实现多余部分裁剪&#xff0c;形成视口内放大缩小 // 程序&#xff1a;2D RPG 地图编辑器与摄像机追随 // 作者&#xff1a;bilibili 民用级脑的研发…

iPhone 数据恢复软件 – 恢复丢失的 iPhone 数据

恢复丢失的 iPhone 数据&#xff0c;奇客数据恢复iPhone版。如今的 iPhone 用户在他们的设备上存储了大量数据&#xff0c;从照片和与亲人的文本对话到商业和医疗信息。其中一些是保密的&#xff1b;其中大部分内容都是非常个人化的&#xff1b;而且大多数一旦丢失就无法替代。…

禅道20.0.stable发布啦,重构底层PHP和UI框架,用户体验全新升级

禅道20.0.stable版本终于正式发布啦&#xff01; 自2023年4月启动以来&#xff0c;经过一年多的努力&#xff0c;我们动员了全公司的产研力量&#xff0c;致力于为用户提供全新的用户体验。 本次版本升级主要包括两个方面&#xff1a;一是用户体验全新升级&#xff0c;二是整体…

软胶囊弹性检测:确保药品质量与患者安全的关键步骤

软胶囊弹性检测&#xff1a;确保药品质量与患者安全的关键步骤 在医药领域&#xff0c;软胶囊作为一种常见的药物载体&#xff0c;其质量的优劣直接关系到药物的有效性和患者的安全。软胶囊的弹性作为其质量评估的重要指标之一&#xff0c;不仅影响其储存和运输的稳定性&#x…

【odoo bug排查】psycopg2.InterfaceError: Cursor already closed

错误日志 Traceback (most recent call last):File "/Users/mzwang/Documents/codes/python/im_test_system/odoo/api.py", line 983, in getcache_value field_cache[record._ids[0]] KeyError: 3During handling of the above exception, another exception occur…

一分钟教你学浪app视频怎么缓存

你是否在学浪app上苦苦寻找如何缓存视频的方法&#xff1f;你是否想快速、轻松地观看自己喜欢的视频内容&#xff1f;那么&#xff0c;让我们一起探索一分钟教你如何缓存学浪app视频的技巧吧&#xff01; 学浪下载工具我已经打包好了&#xff0c;有需要的自己下载一下 学浪下…

[QNX] BSP 网络性能优化:调优io-pkt和ClockPeriod提升网速

0 概要 本文介绍如何在QNX系统上优化网络性能&#xff0c;主要通过调整io-pkt和ClockPeriod参数来实现。通过优化&#xff0c;网络吞吐量可以得到显著提升。 1 优化方法 1.1 调整io-pkt的mclbytes参数: io-pkt是QNX系统中常用的网络协议栈&#xff0c;其mclbytes参数指定了…

如何安全可控地进行内外网跨网络传输文件?

跨网络传输文件通常指的是在不同的网络环境之间移动数据&#xff0c;这在现代企业运营中非常常见。随着网络技术的高速发展&#xff0c;为了有效地保护内部的核心数据资产&#xff0c;企业一般会采用内外网隔离的策略。在进行内外网跨网络传输文件时&#xff0c;需要考虑多种因…

微软exchange邮箱发送

使用java发送exchange类型的邮件&#xff0c;foxmail中配置如下图&#xff1a; 需要的maven依赖如下&#xff1a; <dependency><groupId>com.microsoft.ews-java-api</groupId><artifactId>ews-java-api</artifactId><version>2.0</ve…

报表控件Stimulsoft在JavaScript报告工具中的事件:查看器事件(下)

Stimulsoft Ultimate &#xff08;原Stimulsoft Reports.Ultimate&#xff09;是用于创建报表和仪表板的通用工具集。该产品包括用于WinForms、ASP.NET、.NET Core、JavaScript、WPF、PHP、Java和其他环境的完整工具集。无需比较产品功能&#xff0c;Stimulsoft Ultimate包含了…