qt中根据数据解析的结果动态的创建控件并布局

该示例介绍了一个Qt应用程序,它从JSON配置文件中读取数据,动态创建和布局按钮,以显示班级学生的成绩信息。程序能够处理多个班级,每个班级包括学生姓名和成绩,当数据超出窗口大小时,自动添加滚动条。通过解析JSON文件,实现了灵活的界面更新和布局管理。
摘要由CSDN通过智能技术生成

引言

有时候程序中的控件的个数是无法预测的,当程序启动时,根据解析的数据动态的创建n行m列的控件,并为其布局。下面记录一下动态创建控件,并布局。

运行效果

在这里插入图片描述

示例

此示例主要是从json配置文件中读取参数,然后根据参数的个数创建姐买你上的控件并布局。
下面是具体的实现代码:
main.cpp

#include "studentscoredialog.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    StudentScoreDialog w;
    w.show();
    return a.exec();
}

studentscoredialog.h

#ifndef STUDENTSCOREDIALOG_H
#define STUDENTSCOREDIALOG_H

/********************************************
        ======功能描述:=======
        1.根据解析的数据动态创建按钮,并布局,
        2.数据太多超过显示的窗口的大小时,自动添加滚动条。
********************************************/

#include <QDialog>

//具体学生成绩结构
typedef struct studentInfo
{
    QString name;//学生姓名
    qreal   score;//学生成绩
}ST_STUDENTINFO;
typedef ST_STUDENTINFO stuStudent;
typedef struct scoreInfo
{
    QString strClass;//班级
    qreal   arvgScore;//平均成绩
    qreal   totalScore;//总成绩
    uint8_t number;//人数
    QList<stuStudent> students;//学生成绩列表
}ST_SCOREINFO;
typedef ST_SCOREINFO stuScore;

class QVBoxLayout;
QT_BEGIN_NAMESPACE
namespace Ui { class StudentScoreDialog; }
QT_END_NAMESPACE

class StudentScoreDialog : public QDialog
{
    Q_OBJECT

public:
    StudentScoreDialog(QWidget *parent = nullptr);
    ~StudentScoreDialog();
protected:
    QString getExePath();//获取可执行文件的路径
    void readStudentJsonFile();//读取json文件
    void parseJsonContent(QByteArray &array);//解析json文件内容
    void createCtrl();//创建控件
    void createEveryClassScore(stuScore &score,QVBoxLayout *vLayout);//创建每一个班级的成绩情况
private:
    Ui::StudentScoreDialog *ui;
    QList<stuScore>         m_stuScoreList;//保存从json文件读取的变量值
};
#endif // STUDENTSCOREDIALOG_H

studentscoredialog.cpp

#include "studentscoredialog.h"
#include "ui_studentscoredialog.h"
#include <QCoreApplication>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonParseError>
#include <QFile>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QDebug>

StudentScoreDialog::StudentScoreDialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::StudentScoreDialog)
{
    ui->setupUi(this);

    setWindowFlags(Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
    readStudentJsonFile();
    createCtrl();
}

StudentScoreDialog::~StudentScoreDialog()
{
    delete ui;
}

QString StudentScoreDialog::getExePath()
{
    return QCoreApplication::applicationDirPath();
}

void StudentScoreDialog::readStudentJsonFile()
{
    QString strPath = getExePath() + "/students.json";
    QFile file(strPath);
    if (file.open(QIODevice::ReadOnly)) {
        QByteArray byteArray = file.readAll();
        file.close();
        parseJsonContent(byteArray);
    }else {
        qDebug()<<QStringLiteral("文件打开失败!");
    }
}

void StudentScoreDialog::parseJsonContent(QByteArray &array)
{
    QJsonParseError parseError;
    QJsonDocument doc = QJsonDocument::fromJson(array,&parseError);
    if (!doc.isEmpty() && parseError.error == QJsonParseError::NoError) {
        QJsonObject rootObject = doc.object();

        if (rootObject.value("msg").toString() == "score") {
            QJsonArray resultArray = rootObject.value("results").toArray();
            for (int i = 0; i < resultArray.size(); ++i) {
                QJsonObject resultObject = resultArray[i].toObject();
                stuScore tempScore;
                tempScore.strClass = resultObject.value("class").toString();
                tempScore.arvgScore = resultObject.value("averageScore").toDouble();
                tempScore.totalScore = resultObject.value("totalScore").toDouble();
                tempScore.number = resultObject.value("number").toInt();
                QJsonArray studentArray = resultObject.value("students").toArray();
                for (int j = 0; j < studentArray.size(); ++j) {
                    stuStudent tempStudent;
                    QJsonObject studentObject = studentArray.at(j).toObject();
                    tempStudent.name = studentObject.value("name").toString();
                    tempStudent.score = studentObject.value("score").toDouble();
                    tempScore.students.append(tempStudent);
                }
                m_stuScoreList.append(tempScore);
            }
        }
    }
}

void StudentScoreDialog::createCtrl()
{
    QWidget *widget = ui->scrollAreaWidgetContents;
    QVBoxLayout *vLayout = new QVBoxLayout(widget);
    vLayout->setSpacing(5);
    vLayout->setContentsMargins(5,5,5,5);

    for (int i = 0;  i < m_stuScoreList.size(); ++i) {
        QGroupBox *groupBox = new QGroupBox;
        QVBoxLayout *groupVlayout = new QVBoxLayout(groupBox);
        groupVlayout->setSpacing(5);
        groupVlayout->setContentsMargins(5,0,5,0);
        stuScore classScore = m_stuScoreList.at(i);
        createEveryClassScore(classScore,groupVlayout);

        vLayout->addWidget(groupBox);
    }
}

void StudentScoreDialog::createEveryClassScore(stuScore &score, QVBoxLayout *vLayout)
{
    QHBoxLayout *hLayout = new QHBoxLayout;
    QLabel *classLabel = new QLabel(QStringLiteral("班级:"));
    QLineEdit *classEdit = new QLineEdit(score.strClass);
    QLabel *averageLabel = new QLabel(QStringLiteral("平均成绩:"));
    QLineEdit *averageEdit = new QLineEdit(QString::number(score.arvgScore));
    QLabel *totalLabel = new QLabel(QStringLiteral("总成绩:"));
    QLineEdit *totalEdit = new QLineEdit(QString::number(score.totalScore));
    QLabel *numberLabel = new QLabel(QStringLiteral("人数:"));
    QLineEdit *numberEdit = new QLineEdit(QString::number(score.number));
    hLayout->addWidget(classLabel);
    hLayout->addWidget(classEdit);
    hLayout->addWidget(averageLabel);
    hLayout->addWidget(averageEdit);
    hLayout->addWidget(totalLabel);
    hLayout->addWidget(totalEdit);
    hLayout->addWidget(numberLabel);
    hLayout->addWidget(numberEdit);
    vLayout->addLayout(hLayout);

    QHBoxLayout *scoreLayout = nullptr;
    for (int i = 0; i < score.students.size(); ++i) {
        if (i % 4 == 0) {
            scoreLayout = new QHBoxLayout;
            scoreLayout->setSpacing(5);
            scoreLayout->setContentsMargins(0,0,0,0);
            vLayout->addLayout(scoreLayout);
        }
        stuStudent tempStudent = score.students[i];
        QLabel *nameLabel = new QLabel(QStringLiteral("姓名:"));
        QLineEdit *nameEdit = new QLineEdit(tempStudent.name);
        nameEdit->setFixedWidth(120);
        QLabel *scoreLabel = new QLabel(QStringLiteral("成绩:"));
        QLineEdit *scoreEdit = new QLineEdit(QString::number(tempStudent.score));
        scoreEdit->setFixedWidth(50);
        scoreLayout->addWidget(nameLabel);
        scoreLayout->addWidget(nameEdit);
        scoreLayout->addWidget(scoreLabel);
        scoreLayout->addWidget(scoreEdit);
        if (i == score.students.size() - 1 && score.students.size() % 4 != 0) {
            scoreLayout->addStretch();
        }
    }
}

ui文件中添加的控件:
在这里插入图片描述
创建的项目的结构:
在这里插入图片描述
此项目中读取的配置文件students.json,配置文件的内容如下:
students.json

{
	"msg":"score",
	"results":[
	{
		"class":"二年级一班",
		"averageScore":78,
		"totalScore":936,
		"number":12,
		"students":[{
			"name":"李明",
			"score":77
		},{
			"name":"胡书",
			"score":77
		},{
			"name":"扫速度",
			"score":79
		},{
			"name":"山山倒",
			"score":80
		},{
			"name":"阿萨",
			"score":68
		},{
			"name":"维欧",
			"score":77
		},{
			"name":"奇数",
			"score":75
		},{
			"name":"使能",
			"score":78
		},{
			"name":"水浇地",
			"score":69
		},{
			"name":"当数据",
			"score":87
		},{
			"name":"但是",
			"score":76
		},{
			"name":"撒口",
			"score":79
		}]
	},{
		"class":"二年级二班",
		"averageScore":80,
		"totalScore":960,
		"number":12,
		"students":[{
			"name":"蛋黄酥",
			"score":77
		},{
			"name":"随机",
			"score":79
		},{
			"name":"奥斯基",
			"score":80
		},{
			"name":"赛德克",
			"score":78
		},{
			"name":"收到",
			"score":83
		},{
			"name":"卡松",
			"score":77
		},{
			"name":"欧俄",
			"score":86
		},{
			"name":"撒旦",
			"score":78
		},{
			"name":"喀什",
			"score":84
		},{
			"name":"科奥",
			"score":87
		},{
			"name":"杰斯",
			"score":76
		},{
			"name":"欧维",
			"score":83
		}]
	}
	]
}

整个工程就如上面所示,程序启动的时候根据从配置文件中获取的参数来创建控件,并布局,上面虽使用了栅格布局,但设置了姓名和成绩的控件的宽度,故而将窗口最大化之后不能很完美的显示控件,即成绩和姓名行编辑器没有被拉伸,注释掉对姓名和成绩行编辑器的宽度设置后可以最大化窗口,同时拉伸控件。

  • 2
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 树莓派是一种单板计算机系统,可以通过各种传感器采集到不同类型的数据。要在Qt上位机实时显示树莓派采集到的数据,可以按照以下步骤进行: 1. 在树莓派上编写数据采集程序:使用合适的编程语言(如Python)编写程序,在程序连接传感器并采集数据。可以使用相关库(如RPi.GPIO或sense-hat库)来方便地进行IO控制和数据采集。 2. 在树莓派上设置数据传输通信:将采集到的数据通过适合的通信方式传输给Qt上位机。常见的通信方式有串口通信、网络通信等。可以使用相应的通信库(如pySerial)来实现数据的传输。 3. 在Qt上位机编写数据接收程序:使用C++编写Qt程序,在程序接收树莓派传输的数据。可以使用Qt的串口通信库或网络通信库来接收数据。 4. 在Qt上位机实时显示数据:使用Qt的界面设计工具,在界面添加显示数据控件(如文本框、图表等)。在接收到新的数据时,可以通过信号与槽机制将数据更新到界面上的相应控件。 5. 运行程序并连接树莓派与Qt上位机:确保树莓派和Qt上位机通过相应通信方式正确连接。启动树莓派上的数据采集程序和Qt上位机数据接收程序,即可实时显示从树莓派采集到的数据。 总结起来,要在Qt上位机实时显示树莓派采集到的数据,需要在树莓派和Qt上位机分别编写相应的程序,并通过合适的通信方式进行数据传输和接收。 ### 回答2: 树莓派是一种功能强大的微型计算机,可以用于数据采集和处理。如果想要将树莓派采集到的数据实时显示在Qt上位机上,可以按照以下步骤进行操作: 1. 首先,确保树莓派和Qt上位机能够进行通信。可以使用网络连接、串口通信或其他方式进行通信。 2. 在树莓派上编写数据采集的代码。根据具体需求,可以使用传感器、模块或其他硬件设备采集数据,并将数据存储在树莓派上。 3. 编写与Qt上位机通信的代码。在Qt上位机上,通过网络连接或串口通信,与树莓派建立连接并发送指令进行数据通信。 4. 在Qt上位机创建图形界面,用于显示树莓派采集到的数据。可以使用Qt提供的控件,如图表控件或文本框控件,将数据实时地显示出来。 5. 在Qt上位机设置定时器,定时从树莓派获取数据,并更新显示数据的界面。 6. 编写数据处理的代码。根据具体需求,对从树莓派采集到的数据进行处理、计算或分析,并在Qt上位机的界面上显示处理结果。 7. 调试和测试。确保树莓派和Qt上位机之间的通信正常,数据能够准确地被获取和实时显示。 总而言之,树莓派采集到的数据Qt上位机实时显示需要建立通信连接、编写数据采集和处理的代码,并在Qt界面实时更新数据显示。 ### 回答3: 在树莓派采集数据并在Qt上位机实时显示,可以通过以下步骤实现: 1. 在树莓派上编写一个数据采集程序,使用传感器或其他设备获取数据。该程序可以使用Python或其他编程语言编写,并以一定的频率读取传感器数据。 2. 将采集到的数据通过网络传输到Qt上位机。可以使用网络通信协议,如TCP/IP或UDP,编写树莓派上的数据发送程序。 3. 在Qt上位机编写一个数据接收程序,通过网络接收来自树莓派的数据。可以使用Qt提供的网络编程类库,如QTcpServer和QTcpSocket,从树莓派接收数据。 4. 在Qt上位机的界面创建一个用于实时显示数据的窗口或控件。可以使用Qt的图形化界面设计工具,如Qt Designer,设计好界面布局。 5. 在Qt上位机的数据接收程序解析接收到的数据,并将其显示在界面上的窗口或控件。可以使用Qt提供的图表类库,如QChart或QCustomPlot,将数据绘制成实时曲线图或其他形式的图表。 6. 在数据接收程序,使用定时器或其他机制,定期更新界面上的数据显示,以实现实时更新。 7. 编译和部署Qt上位机程序,并将其运行在Qt支持的操作系统上,如Windows、Linux或Mac OS。 通过以上步骤,树莓派采集到的数据可以实时传输到Qt上位机,并通过图形界面实时显示。这样,用户可以方便地监测和分析采集到的数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肩上风骋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值