Qt Quick读取本地文件并显示成表格

news2024/10/7 14:31:17

🚀作者:CAccept
🎂专栏:Qt Quick
在这里插入图片描述

文章目录

  • 🍎C++代码部分实现
  • 🚀C++类注册到QML中
  • 🎂QML部分实现
  • 🌰小知识点
    • ⭐C++与QML进行交互
    • ⭐将运行路径进行传递保证程序的稳定性
    • ⭐QML中定义信号其默认的槽方法是on+大写信号名

🍎C++代码部分实现

C++代码部分负责读取本地的文本文件,通过规则将文件进行解析,然后再通过信号与槽机制将数据传递给QML中供其使用,现在让我们来看看思路吧。
实现思路:
1、在QML中实现QML的信号和FileLoad槽方法的绑定
2、QML触发信号并将文件路径传递给FileLoad
3、一行一行解析数据
4、每次解析完一行数据就将一行数据利用信号传给QML,用于添加表格数据



fileload.h

#ifndef FILELOAD_H
#define FILELOAD_H

#include <QObject>
#include <QString>
#include <QUrl>
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
class FileLoad : public QObject
{
    Q_OBJECT
public:
    explicit FileLoad(QObject *parent = nullptr);
    //解析一行数据
    void parseLineData(QString line);
signals:
	//由于文件有9列所以就搞了9个参数,来传递数据
    void sendFileData(QString p1,QString p2,QString p3,QString p4,QString p5,QString p6,QString p7,QString p8,QString p9);
public slots:
	//读取整体文件
    void fileRead(QString fileName);

};

#endif // FILELOAD_H

fileload.cpp

#include "fileload.h"
#include <QDebug>
FileLoad::FileLoad(QObject *parent) : QObject(parent)
{

}

void FileLoad::parseLineData(QString line)
{
    //将line前面的空格进行去除
    line.remove (QRegExp ("^ +\s*"));
    //以四个空格为分隔符进行分割
    QStringList list = line.split("   ");
    QStringList data;
    int count = 0;
    for(auto parameter:list){
    	//去除字符串两边的空格
        parameter = parameter.simplified();
        count++;
        data.push_back(parameter);
    }
    for(int i=0;i<count;i++)
    {
        qDebug()<<data[i];
    }
    if(count == 9)
    {
    	//发送信号
        emit sendFileData(data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7],data[8]);
    }
}

void FileLoad::fileRead(QString fileName)
{
    //qDebug()<<"开始fileRead!"<<endl;
    QFile f(fileName);
    if (!f.open(QIODevice::ReadOnly|QIODevice::Text))//打开指定文件
    {
        qDebug()<<"没有找到文件!!";
        return;
    }

    QTextStream txtInput(&f);
    QString lineStr;
    while (!txtInput.atEnd())
    {
        lineStr = txtInput.readLine();  //读取数据
		//解析这一行的数据
        parseLineData(lineStr);
    }

    f.close();
}


🚀C++类注册到QML中

注册过程:
1、main.cpp包含头文件fileload.h
2、创建FileLoad对象
3、engine.rootContext()->setContextProperty对FileLoad对象进行注册
main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QDir>
#include <QApplication>
#include <QQmlContext>
#include <fileload.h>
int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QApplication app(argc, argv);
    QString path = QCoreApplication::applicationDirPath();
    //创建FileLoad对象
    FileLoad fileload;
    QQmlApplicationEngine engine;
    //将path传递进去,方便调用路径查找文件
    engine.rootContext()->setContextProperty("appDir",path);
    engine.rootContext()->setContextProperty("fileload", &fileload);
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);
    return app.exec();
}

🎂QML部分实现

QML部分的实现关键点在👇
1、定义信号

signal qmlGetData(string p1, string p2, string p3,string p4, string p5, string p6,string p7, string p8, string p9)
//将地址送给fileload,让fileload解析
signal qmlFilePathAccepted(string filename)

2、将QML定义的信号与C++类对象fileload的槽方法进行连接

//将qmlFilePathAccepted和fileload的槽方法fileRead进行连接
qmlFilePathAccepted.connect(fileload.fileRead)

3、将C++类对象fileload的信号实现对应的槽方法

//绑定信号槽
Connections{
    target: fileload
    //实现fileload中sendFileData信号对应的槽方法
    function onSendFileData(p1,p2,p3,p4,p5,p6,p7,p8,p9)
    {
    	//发射信号
        qmlGetData(p1,p2,p3,p4,p5,p6,p7,p8,p9)
    }
}

4、实现qmlGetData对应响应的槽方法

onQmlGetData:
{
	 //给model后面追加数据
     listModel.append({"p1":p1,"p2":p2,"p3":p3,"p4":p4,"p5":p5,"p6":p6,"p7":p7,"p8":p8,"p9":p9})
}

5、实现表格的显示

main.qml

import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Layouts 1.2
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.2

Window {
    id:gridArea
    width: 1050;
    height: 457
    visible: true
    signal qmlGetData(string p1, string p2, string p3,string p4, string p5, string p6,string p7, string p8, string p9)
    signal qmlFilePathAccepted(string filename)
    onQmlGetData:
    {
        console.log("触发qmlGetData")
        listModel.append({"p1":p1,"p2":p2,"p3":p3,"p4":p4,"p5":p5,"p6":p6,"p7":p7,"p8":p8,"p9":p9})
    }

    TableView {
        id: tableView
        objectName: "tableView"
        anchors.fill: parent

        TableViewColumn {
            id: p1
            title: "p1"
            role: "p1"
            width:60

        }
        TableViewColumn {
            id: p2
            title: "p2"
            role: "p2"
            width:60
        }
        TableViewColumn {
            id: p3
            title: "p3"
            role: "p3"
            width:60
        }
        TableViewColumn {
            id: p4
            title: "p4"
            role: "p4"
            width:60

        }
        TableViewColumn {
            id: p5
            title: "p5"
            role: "p5"
            width:60

        }
        TableViewColumn {
            id: p6
            title: "p6"
            role: "p6"
            width:60

        }
        TableViewColumn {
            id: p7
            title: "p7"
            role: "p7"
            width:60

        }
        TableViewColumn {
            id: p8
            title: "p8"
            role: "p8"
            width:60

        }
        TableViewColumn {
            id: p9
            title: "p9"
            role: "p9"
            width:60

        }

        model: ListModel {
            id: listModel
            objectName: "listModel"

        }
    }
    //绑定信号槽
    Connections{
        target: fileload
        //实现fileload中sendFileData信号对应的槽方法
        function onSendFileData(p1,p2,p3,p4,p5,p6,p7,p8,p9)
        {
            qmlGetData(p1,p2,p3,p4,p5,p6,p7,p8,p9)
        }
    }

    Component.onCompleted: {
    	//将qmlFilePathAccepted和fileload的槽方法fileRead进行连接
        qmlFilePathAccepted.connect(fileload.fileRead)
        //将传进行来的appDir运行路径进行组合这样更好,且移植性强
        qmlFilePathAccepted(appDir+"/inpparameter.DAT")
    }
}

我的文件👇
在这里插入图片描述

运行效果👇
在这里插入图片描述


🌰小知识点

⭐C++与QML进行交互

将C++类注册到QML中一般有两种方法
1、qmlRegisterType函数

int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName);

第一个参数uri指的是QML中import后的内容,相当于头文件名,第二个第三个参数分别是主次版本号,第四个指的是QML中类的名字(第四个QML的类名首字母一定要大写,要不然会报错)。<>中放的是C++的类的名字

qmlRegisterType则用于向QML引擎注册一个新的类型,该类型可以在QML代码中直接创建。这种方法适用于需要在QML中创建新对象或自定义组件时使用。通过qmlRegisterType函数注册后,我们就可以在QML代码中像使用其他标准类型一样使用该类型了。

//在main.cpp中使用👇
qmlRegisterType<qan::RightResizer>("QuickQanava", 2, 0, "RightResizer");
//那么我们在qml文件中就要👇
import QuickQanava 2.0 as Qan
Qan.RightResizer{
   balabala
   ..... 
   ....
}

2、engine->rootContext()->setContextProperty

engine.rootContext()->setContextProperty用于将一个现有的C++对象实例暴露给QML引擎。这种方法适合于简单的场景,例如在QML中调用C++对象中的方法或访问其属性等。我们可以使用以下代码将C++对象实例暴露给QML引擎:

// C++对象
MyObject myObject;
// 将myObject暴露给QML引擎,这样就可以在QML文件中使用myObject来控制和使用我们外面定义的C++对象myObject
engine.rootContext()->setContextProperty("myObject", &myObject);

engine->rootContext()->setContextProperty更适用于一些简单的场景不需要多次创建,整个过程就只要存在一个这个对象就可以,而qmlRegisterType就相当于创建了一个新的类型,可以反复给QML创建


⭐将运行路径进行传递保证程序的稳定性

可以通过Qt的API得到当前程序的执行路径,然后通过注册将路径传递给QML使用,这样就可以在一定程度上保证程序的可移植性👇
main.cpp

QString path = QCoreApplication::applicationDirPath();
engine.rootContext()->setContextProperty("appDir",path);

在qml中就可以这样使用👇

qmlFilePathAccepted(appDir+"/inpparameter.DAT")

⭐QML中定义信号其默认的槽方法是on+大写信号名

signal qmlGetData(string p1, string p2, string p3,string p4, string p5, string p6,string p7, string p8, string p9)
onQmlGetData:
{
   listModel.append({"p1":p1,"p2":p2,"p3":p3,"p4":p4,"p5":p5,"p6":p6,"p7":p7,"p8":p8,"p9":p9})
}

感谢您看完了这篇文章,希望这篇文章对您有所帮助,当然,如果在这篇文章中有遇到一些问题或者疑问的话请一定在评论区中提出万分感谢!!
在这里插入图片描述

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

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

相关文章

【Proteus仿真】【STM32单片机】智能加湿器设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真STM32单片机控制器&#xff0c;使用LCD1602液晶、按键、蜂鸣器、DHT11温湿度传感器、水位传感器、PCF8591 ADC、继电器、加湿装置等。 主要功能&#xff1a; 系统运行后&#xff0…

从零开始:深入理解Kubernetes架构及安装过程

K8s环境搭建 文章目录 K8s环境搭建集群类型安装方式环境规划克隆三台虚拟机系统环境配置集群搭建初始化集群&#xff08;仅在master节点&#xff09;配置环境变量&#xff08;仅在master节点&#xff09;工作节点加入集群&#xff08;knode1节点及knode2节点&#xff09;安装ca…

吃鸡高手秘籍大揭秘,享受顶级游戏干货!

大家好&#xff01;作为吃鸡行家&#xff0c;今天我将揭示一些与众不同、足够吸引力的内容&#xff0c;帮助您提高游戏战斗力并分享顶级游戏作战干货。 首先&#xff0c;让我们推荐一些绝地求生作图工具。这些工具可以帮助您在游戏中更好地制作作战图和规划策略&#xff0c;让您…

基于RuoYi-Flowable-Plus的若依ruoyi-nbcio支持本地图片上传与回显的功能实现(二)

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 排除路径&#xff0c;增加avatar图片 # security配置 security:# 排除路径excludes:# 静态资源- /*.html…

Python+Tkinter 图形化界面基础篇:集成数据库

PythonTkinter 图形化界面基础篇&#xff1a;集成数据库 引言为什么选择 SQLite 数据库&#xff1f;集成 SQLite 数据库的步骤示例&#xff1a;创建一个任务管理应用程序步骤1&#xff1a;导入必要的模块步骤2&#xff1a;创建主窗口和数据库连接步骤3&#xff1a;创建数据库表…

Spring源码解析—— AOP代理的生成

本文已经收录到大彬精心整理的大厂面试手册&#xff0c;包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等高频面试题&#xff0c;非常实用&#xff0c;有小伙伴靠着这份手册拿…

(1)(1.3) 匿名航空电子设备DroneCAN激光雷达接口

文章目录 前言 1 设置参数 2 参数说明 前言 Avionics Anonymous DroneCAN 激光雷达接口是一个微型接口(Avionics Anonymous DroneCAN LIDAR Interface)&#xff0c;适用于几种常见的激光测距仪(several common laser rangefinders)&#xff0c;可通过 DroneCAN 连接到 Pixha…

混淆技术研究笔记(五)混淆后如何反篡改?

有了上一节的基础工具后&#xff0c;接下来要考虑如何反篡改。 本文采用的是对混淆后的代码&#xff0c;针对某些关键包的字节码数据计算md5值&#xff0c;对所有类计算完成后对md5值进行排序&#xff0c;排序后拼接字符串再次计算md5值&#xff0c;最后通过私钥对md5进行RSA对…

Linux之open和fopen的比较

1、fopen 是ANSIC标准中的C库函数&#xff0c;open是系统调用 2、fopen提供了IO缓存功能&#xff0c;而open没有&#xff0c;所以fopen速度要比open快 3、fopen具有良好的移植性&#xff0c;而open 是依赖于特定的环境 4、fopen返回一个FILE 结构体指针&#xff0c;而open 返…

MES管理系统如何解决电子企业的生产痛点

随着电子行业的快速发展&#xff0c;企业面临着越来越多的生产和管理挑战。其中&#xff0c;物料编码管理困难、产品设计工作繁重、客户需求多样化 以及产品设计变更管理困难等问题尤为突出。为了解决这些问题&#xff0c;许多电子企业开始引入MES管理系统解决方案&#xff0c;…

如何实现响应式网页设计?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

做直播或短视频 其实有几个精准粉丝就可以很快变现

随着短视频 和 直播 快速发展 人流量巨大 只要是个东西 只要你能豁得出去 都能卖出去 把精准流量引流到自己的私域里面 可以组建团队 一起发展 自己喝点汤就好 有一起做CSDN和其他短视频项目的 可以左上方私信留言 我怕说多了 审核不过去

Svelte生命周期(加整体概述)

目录 前言 一、编译阶段 1. 导入语句 2. 组件声明 3. 模板部分 4. CSS样式 二、运行时阶段 三、生命周期函数 1. onMount 2. beforeUpdate 与 afterUpdate 3. onDestroy 4. setContext 与 getContext 6. hasContext 7. getAllContexts 前言 Svelte是一种现代的Ja…

冠军代言|媒介易:释放品牌潜力,实力助力,助您势如破竹!

在竞争激烈的市场中&#xff0c;品牌需要不断创新&#xff0c;找到吸引目标客户的方法。而与体育冠军合作&#xff0c;通过冠军代言&#xff0c;已经成为了众多企业提高品牌知名度、树立形象、吸引消费者目光的重要策略之一。在这个领域&#xff0c;媒介易以其实力加冕&#xf…

如何正确高效使用墨西哥专线?

在当今全球化的物流行业中&#xff0c;跨境运输服务已经成为许多企业拓展国际市场的重要手段。然而&#xff0c;由于各国法律法规、文化差异以及运输环节的复杂性&#xff0c;企业在进行跨境运输时可能会遇到诸多挑战。为了解决这些问题&#xff0c;一些专业的物流公司推出了“…

浅谈电能质量监测装置在某半导体公司的应用

摘 要&#xff1a;半导体生产制造业在国民经济中起着举足轻重的作用&#xff0c;相关企业的规模也越来越大。其供配电系统稳定、可靠的运维不仅是其安全生产的基本保证&#xff0c;还关系到产品质量和生产的顺利进行。而半导体行业中大部分工艺设备对电能质量比较敏感&#xff…

KEIL5添加沁恒的ch55x芯片(其他非arm和stm32芯片也可使用类似的方法)

准备工作 参考&#xff1a;https://www.iotword.com/8615.html 已经安装好keil5的软件环境 烧录工具下载 沁恒烧录工具地址&#xff0c;下载安装后如下图 操作步骤 打开从沁恒官网下载安装好的WHCISPTOOL软件 安装下图中的操作方式完成对安装软件keil5中的配置文件的生…

京东商品列表数据接口,关键词搜索京东商品数据接口

在网页抓取方面&#xff0c;可以使用 Python、Java 等编程语言编写程序&#xff0c;通过模拟 HTTP 请求&#xff0c;获取京东网站上的商品页面。在数据提取方面&#xff0c;可以使用正则表达式、XPath 等方式从 HTML 代码中提取出有用的信息。值得注意的是&#xff0c;京东网站…

Camtasia Studio2024最新版本正式更新上线!

Camtasia Studio2024是一款专门录制屏幕动作的工具&#xff0c;它能在任何颜色模式下轻松地记录 屏幕动作&#xff0c;包括影像、音效、鼠标移动轨迹、解说声音等等&#xff0c;简单实用的视频录制软件,游戏的精彩画面,网络视频,屏幕录制可以让您录制屏幕所有内容视频录制支持3…

1806_emacs_org-mode归档的时候修改归档文件名称

全部学习汇总&#xff1a;GreyZhang/g_org: my learning trip for org-mode (github.com) 前面已经基本了解了org-mode的归档的规则或者方法&#xff0c;但是还有一点跟我现在的工作流有点不相符。我自己的工作流中会每月做一次工作的整理总结&#xff0c;因此归档的文件是按照…