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.12


Window {
    id:window
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    //信号
    signal addSig(string s)
    signal updateSig(int id,string s)
    signal onEnterPressedSig(int id,string s)

    ComboBox{
        id:comboBox
        x:10
        y:10
        z:1
        width:150
        height: 40
        model:MyListModel
        currentIndex: 0
        font.pointSize: 12
        editable: true //允许编辑

        delegate:ItemDelegate
        {
            id:delegate
            width:comboBox.width
            height: comboBox.height
            contentItem: Text{
                text:name
                anchors.fill:parent
                color:"black"
                font:comboBox.font
                elide:Text.ElideRight
                verticalAlignment: Text.AlignVCenter
            }
            highlighted: index === comboBox.highlightedIndex//悬浮
        }

        Component.onCompleted:
        {
            comboBox.editText = "请选择"
            addSig.connect(MyListModel.addSlot)
            updateSig.connect(MyListModel.updateSlot)
            onEnterPressedSig.connect(MyListModel.onEnterPressedSlot)
        }

        Button
        {
            x:50
            y:50
            id:btn
            text:"新增"
            onClicked:
            {
                var editText = comboBox.editText;
                addSig(editText);
                comboBox.currentIndex = MyListModel.rowCount()-1;
                console.log("currentIndex is ",comboBox.currentIndex);
            }
        }

        Button
        {
            x:50
            y:100
            id:btn2
            text:"修改"
            onClicked:
            {
                var currentIndex = comboBox.currentIndex-1;
                var editText = comboBox.editText;
                updateSig(currentIndex,editText);
            }
        }
    }
}

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

4、总结

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大模型入坑记:搭建本地大模型微调环境

为了让大模型发挥更大用途&#xff0c;决定在本地搭建大模型微调环境&#xff0c;在原有的PC上加装Tesla V100&#xff0c;前前后后耗时一个多月&#xff0c;遇到若干技术问题&#xff0c;好在目前已基本得到解决&#xff0c;也打破了很多网上店家包括身边专家对GPU搭建上的一些…

正版软件 | Total Uninstall - Windows 全功能卸载程序 新手入门教程

『软件简介』 Total Uninstall 是一款先进的系统监控与卸载工具&#xff0c;它通过创建安装前后的系统快照&#xff0c;为用户提供了一种全新的程序管理方式。这款软件具备两个主要功能&#xff1a;一是能够独立于系统自带的卸载程序&#xff0c;彻底移除已安装的应用程序&…

FPGA -手写异步FIFO

一&#xff0c;FIFO原理 FIFO&#xff08;First In First Out&#xff09;是一种先进先出的数据缓存器&#xff0c;没有外部读写地址线&#xff0c;使用起来非常简单&#xff0c;只能顺序写入数据&#xff0c;顺序的读出数据&#xff0c;其数据地址由内部读写指针自动加1完成&a…

开源数据可视化大屏对接表单数据实践!

如果你需要一个表单系统&#xff0c;进行数据收集&#xff1b;可以使用tduck填鸭进行私有化部署&#xff0c;进行表单制作&#xff0c;完成数据收集。 在实际业务中&#xff0c;往往需要将收集的数据进行展示或分析&#xff1b;此时就可以使用表单数据推送到TReport中&#xf…

AMBA总线介绍

AMBA&#xff08;Advanced Microcontroller Bus Architecture&#xff09;是由ARM&#xff08;Advanced RISC Machines&#xff09;公司设计的一种高性能、高带宽的总线架构。AMBA总线广泛应用于各种嵌入式系统中&#xff0c;包括数字信号处理器、图形处理器、嵌入式处理器以及…

收银系统源码--什么是千呼智慧新零售系统?

千呼智慧新零售系统是一套针对零售行业线上线下一体化收银系统。给门店提供线下称重收银、o2o线上商城、erp进销存、精细化会员管理、丰富营销插件等一体化解决方案。多端数据打通&#xff0c;实现线上线下一体化&#xff0c;提升门店工作效率&#xff0c;实现数字化升级&#…

vue3 依赖-组件tablepage-vue3版本1.0.3更新内容

github求⭐ 可通过github 地址和npm 地址查看全部内容 vue3 依赖-组件tablepage-vue3说明文档&#xff0c;列表页快速开发&#xff0c;使用思路及范例-汇总 vue3 依赖-组件tablepage-vue3说明文档&#xff0c;列表页快速开发&#xff0c;使用思路及范例&#xff08;Ⅰ&#…

【第38天】SQL进阶-SQL设计优化-范式设计(SQL 小虚竹)

回城传送–》《100天精通MYSQL从入门到就业》 文章目录 零、前言一、练习题目二、SQL思路初始化数据什么是范式设计第一范式&#xff08;1NF&#xff09;第二范式&#xff08;2NF&#xff09;第三范式&#xff08;3NF&#xff09; 三、总结四、参考 零、前言 今天是学习 SQL …

期权和期货有什么区别?

今天期权懂带你了解期权和期货有什么区别&#xff1f;期权和期货是两种常见的衍生金融工具&#xff0c;它们在结构和盈利方式上存在一些关键的区别&#xff1a; 期权 期权是一种给予持有者在未来某个时间以特定价格买入或卖出基础资产的权利&#xff0c;但不是义务。期权的主要…

ORACLE 19C RAC DIAG进程消耗大量内存的分析

近期一个ORACLE 19C的RAC环境&#xff0c;多次出现数据库实例的后台进程DIAG消耗很多内存&#xff08;达到20G&#xff09;&#xff0c;节点1、节点2都出现过次问题。 问题分析&#xff1a;通过对DIAG进程TRACE分析&#xff0c;结合在ORACLE官方后台进行问题、BUG查询匹配&…

uniapp怎么使用jsx

安装vitejs/plugin-vue-jsx npm install vitejs/plugin-vue-jsx -Dvite.config.js配置 import { defineConfig } from "vite"; import uni from "dcloudio/vite-plugin-uni"; import vueJsx from vitejs/plugin-vue-jsxexport default defineConfig({plu…

初始Java篇(JavaSE基础语法)(7)抽象类和接口(下)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;JavaSE 接上文&#xff1a;初始Java篇&#xff08;JavaSE基础语法&#xff09;&#xff08;7&#xff09;抽象类和接口&#xff08;上&#xf…

Netty HTTP2 示例-响应式编程-013

🤗 ApiHug {Postman|Swagger|Api...} = 快↑ 准√ 省↓ GitHub - apihug/apihug.com: All abou the Apihug apihug.com: 有爱,有温度,有质量,有信任ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplace The Next Generation API Development Platform …

上海亚商投顾:沪指缩量调整 合成生物概念股持续爆发

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指昨日缩量震荡调整&#xff0c;深成指、创业板指均跌超1%。细胞免疫治疗概念股大涨&#xff0c;冠昊生物、…

运营一个在线课堂有哪些基础费用?

我是酷瓜云课堂的作者&#xff0c;对这个问题还是很有心得的。我们的系统是基于腾讯云服务的&#xff0c;下面简单罗列一些基础费用&#xff0c;价格和腾讯云官方有些许出入&#xff0c;仅供参考。 &#xff08;1&#xff09;域名 域名注册通常 60 - 80元 / 年&#xff0c;续…

【JavaEE网络】HTTP响应详解:状态码、报头与正文的全面解析

目录 HTTP响应&#xff08;Response&#xff09;认识 "状态码" (status code)认识响应 “报头”&#xff08;header&#xff09;认识响应 “正文”&#xff08;body&#xff09; HTTP响应&#xff08;Response&#xff09; 响应&#xff1a; 首行响应头空行正文 认…

AI大模型探索之路-训练篇18:大语言模型预训练-微调技术之Prompt Tuning

系列篇章&#x1f4a5; AI大模型探索之路-训练篇1&#xff1a;大语言模型微调基础认知 AI大模型探索之路-训练篇2&#xff1a;大语言模型预训练基础认知 AI大模型探索之路-训练篇3&#xff1a;大语言模型全景解读 AI大模型探索之路-训练篇4&#xff1a;大语言模型训练数据集概…

信息系统项目管理师0095:项目管理知识领域(6项目管理概论—6.4价值驱动的项目管理知识体系—6.4.4项目管理知识领域)

点击查看专栏目录 文章目录 6.4.4项目管理知识领域6.4.4项目管理知识领域 除了过程组,过程还可以按知识领域进行分类。知识领域指按所需知识内容来定义的项目管理领域,并用其所含过程、实践、输入、输出、工具和技术进行描述。 虽然知识领域相互联系,但从项目管理的角度来看…

使用unplugin-icons报错:Icon `eos-icons/ai` not found

代码&#xff1a; import IconNanobert from ~icons/eos-icons/ai 报错&#xff1a; Icon eos-icons/ai not found解决办法&#xff1a; npm i -D iconify-json/eos-icons &#xff08;把eos-icons替换成报错的那个collection-id即可&#xff0c;collection-id名称见图2&…

JVM堆内存分析

jmap工具查看堆内存 jmap:全称JVM Memory Map 是一个可以输出所有内存中对象的工具&#xff0c;可以将JVM中的heap&#xff08;堆&#xff09;&#xff0c;以二进制输出成文本&#xff0c;打印出Java进程对应的内存 找到pid jmap -heap 19792 Attaching to process ID 19792…
最新文章