[QT]qt小项目,使用qcustomplot实时绘制串口波形数据并存储到数据库,可查看历史波形。

前言

        本项目是基于我已学习到的qt知识,将这些知识整合起来做成的一个练手小项目,作者还是新手处于学习阶段,程序中还有很多能够改进的地方,但我能力不足有些问题发现不了。或者有些问题在开发中就已经发现了,但是修改代码太麻烦就没有修改(在代码中会指出)。如果你有什么更好的建议可以留在评论区。

界面展示

主界面

设置界面

查询界面

        预想中是能显示4路数据,两路ADC数据(其他数据传输方式)和两路串口数据,这里只做了串口通信。图像中的曲线是程序生成的测试数据而非串口数据。

串口数据显示(黄色曲线为串口1接收数据)

        这里串口数据显示其实有一个小BUG,之后会提到。

大概框架

        说明一下主要成员变量及其所属父对象。

项目整体结构

其中qcustomplot.h和.cpp文件需要去官网下载,请自行百度,或者直接下载我的工程文件即可。

直接上代码

mainwindow.h 主界面头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QWidget>
#include <QSerialPort>
#include <QSettings>
#include "qcustomplot.h"
#include "setting.h"
#include "search.h"
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QMainWindow>
#define  STR(str)   #str


QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void initMainUi();
    void setSerialPort(QSerialPort*);
    void initDatabase();
    static void setCustomplotStyle(const QString&, QCustomPlot *);
    static void setAxisColor(const QString&, QCustomPlot *);

    enum FixedAxis{
        Graph1FixedAxis = 0x01,
        Graph2FixedAxis = 0x02
    };

private:
    QSerialPort *serialPort1;
    QSerialPort *serialPort2;

private slots:
    void on_setBtn_clicked();

    void on_exitBtn_clicked();

    void on_Uart1Enable_clicked(bool checked);

    void on_Uart2Enable_clicked(bool checked);

    void uart1Recieve();

    void uart2Recieve();

    void realtimeDataSlot();

    void showMainUi();

    void on_searchBtn_clicked();

protected:
    void showEvent(QShowEvent *event) override;
    void closeEvent(QCloseEvent *event) override;
    //void paintEvent(QPaintEvent *event) override;

private:
    Ui::MainWindow *ui;
    QSettings *config;
    QCustomPlot *plot_1;
    QCustomPlot *plot_2;
    QTimer *dataTimer;
    double key;  //用来记录横坐标的时间刻度
    Setting *settingUi;
    Search *searchUi;
    quint8 isFixedAxisRange;
    QSqlDatabase *database;


};
#endif // MAINWINDOW_H

mainwindow.cpp 主界面源文件

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QDebug>


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    //初始化各成员变量
    settingUi = new Setting();
    initDatabase(); //必须在实例化Search对象之前初始化数据库
    searchUi = new Search(database);
    ui->setupUi(this);
    plot_1 = ui->customPlot1;
    plot_2 = ui->customPlot2;
    dataTimer = new QTimer(this);
    //打开配置文件
    config = new QSettings("config.ini", QSettings::IniFormat);
    serialPort1 = new QSerialPort(this);
    serialPort2 = new QSerialPort(this);
    //连接串口接收槽函数
    connect(serialPort1, SIGNAL(readyRead()), this, SLOT(uart1Recieve()));
    connect(serialPort2, SIGNAL(readyRead()), this, SLOT(uart2Recieve()));
    // 使上下轴、左右轴范围同步
    connect(plot_2->xAxis, SIGNAL(rangeChanged(QCPRange)), plot_2->xAxis2, SLOT(setRange(QCPRange)));
    connect(plot_2->yAxis, SIGNAL(rangeChanged(QCPRange)), plot_2->yAxis2, SLOT(setRange(QCPRange)));
    //定时器连接槽函数realtimeDataSlot
    connect(dataTimer, SIGNAL(timeout()), this, SLOT(realtimeDataSlot()));
    //实现关闭设置界面/查询界面 显示主界面
    connect(settingUi, SIGNAL(showMainUi()), this, SLOT(showMainUi()));
    connect(searchUi, SIGNAL(showMainUi()), this, SLOT(showMainUi()));
    //this->setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
    initMainUi();

}

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

void MainWindow::initMainUi()
{
    //串口数据显示区
    //坐标轴使用时间
    QSharedPointer<QCPAxisTickerTime> timeTicker(new QCPAxisTickerTime);
    timeTicker->setTimeFormat("%h:%m:%s");
    //设置曲线颜色(显示区域2)
    plot_2->addGraph();
    plot_2->graph(0)->setPen(QPen(QColor("#4fa08b"))); //测试数据
    plot_2->addGraph();
    plot_2->graph(1)->setPen(QPen(QColor(255, 100, 40))); //串口2
    plot_2->xAxis->setTicker(timeTicker);
    //四边安上坐标轴
    plot_2->axisRect()->setupFullAxesBox();
    //设置坐标轴名字
    plot_2->xAxis->setLabel("时间/h:m:s");
    plot_2->yAxis->setLabel("幅值");
    //plot_2->setBackground(QBrush(QColor(
void Widget::Select() //查询 { QString name = ui->lineEdit->text(); model->setFilter(QObject::tr("id = '%1'").arg(name)); //根据姓名进行筛选 model->select(); //显示结果 } void Widget::Delect() //删除当前行 { int curRow = ui->tableView->currentIndex().row(); //获取选中的行 model->removeRow(curRow); //删除该行 int ok = QMessageBox::warning(this,tr("删除当前行!"),tr("你确定" "删除当前行吗?"), QMessageBox::Yes,QMessageBox::No); if(ok == QMessageBox::No) { model->revertAll(); //如果不删除,则撤销 } else model->submitAll(); //否则提交,在数据库中删除该行 } void Widget::Add() //插入记录 { int rowNum = model->rowCount(); //获得表的行数 int id = 10; model->insertRow(rowNum); //添加一行 model->setData(model->index(rowNum,0),id); //model->submitAll(); //可以直接提交 } void Widget::Back() //返回全表 { model->setTable("student"); //重新关联表 model->setHeaderData(0, Qt::Horizontal, "Time"); model->setHeaderData(1, Qt::Horizontal, "Temperature"); model->select(); //这样才能再次显示整个表的内容 } void Widget::Amend() //提交修改 { model->database().transaction(); //开始事务操作 if (model->submitAll()) { model->database().commit(); //提交 } else { model->database().rollback(); //回滚 QMessageBox::warning(this, tr("tableModel"), tr("数据库错误: %1").arg(model->lastError().text())); } } void Widget::Get_time() { QString string; QTime current_time = QTime::currentTime(); int hour = current_time.hour(); int minute = current_time.minute(); int second = current_time.second(); // int msec = current_time.msec(); string=QString("%1").arg(hour)+":"+QString("%1").arg(minute) +":"+QString("%1").arg(second); ui->Receive->append(string); //qDebug() <rowCount(); //获得表的行数 // int id = 10; model->insertRow(rowNum); //添加一行 model->setData(model->index(rowNum,0),string); model->submitAll(); } void Widget::readMyCom() { QByteArray temp = myCom->readAll(); if(temp.size()!=0) { QString string; QTime current_time = QTime::currentTime(); int hour = current_time.hour(); int minute = current_time.minute(); int second = current_time.second(); // int msec = current_time.msec(); string=QString("%1").arg(hour)+":"+QString("%1").arg(minute) +":"+QString("%1").arg(second); ui->Receive->append(string); //qDebug() <rowCount(); //获得表的行数 // int id = 10; model->insertRow(rowNum); //添加一行 model->setData(model->index(rowNum,0),string); model->setData(model->index(rowNum,1),temp); model->submitAll(); data_light=temp.toInt(); } ui->Receive->append(temp); } void Widget::openCom() { QString portName = ui->portNameComboBox->currentText(); myCom = new Win_QextSerialPort(portName,QextSerialBase::EventDriven); myCom ->open(QIODevice::ReadWrite); if(ui->baudRateComboBox->currentText()==tr("9600")) myCom->setBaudRate(BAUD9600); else if(ui->baudRateComboBox->currentText()==tr("115200")) myCom->setBaudRate(BAUD115200); myCom->setFlowControl(FLOW_OFF); myCom->setTimeout(500); connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom())); ui->openMyComBtn->setEnabled(false); ui->closeMyComBtn->setEnabled(true); ui->baudRateComboBox->setEnabled(false); ui->portNameComboBox->setEnabled(false); }
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值