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

打印 上一主题 下一主题

主题 545|帖子 545|积分 1635



媒介

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

主界面


设置界面


查询界面


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


        这里串口数据显示实在有一个小BUG,之后会提到。
大概框架


        说明一下主要成员变量及其所属父对象。
项目团体结构


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

mainwindow.h 主界面头文件

  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3. #include <QWidget>
  4. #include <QSerialPort>
  5. #include <QSettings>
  6. #include "qcustomplot.h"
  7. #include "setting.h"
  8. #include "search.h"
  9. #include <QSqlDatabase>
  10. #include <QSqlError>
  11. #include <QSqlQuery>
  12. #include <QMainWindow>
  13. #define  STR(str)   #str
  14. QT_BEGIN_NAMESPACE
  15. namespace Ui { class MainWindow; }
  16. QT_END_NAMESPACE
  17. class MainWindow : public QMainWindow
  18. {
  19.     Q_OBJECT
  20. public:
  21.     MainWindow(QWidget *parent = nullptr);
  22.     ~MainWindow();
  23.     void initMainUi();
  24.     void setSerialPort(QSerialPort*);
  25.     void initDatabase();
  26.     static void setCustomplotStyle(const QString&, QCustomPlot *);
  27.     static void setAxisColor(const QString&, QCustomPlot *);
  28.     enum FixedAxis{
  29.         Graph1FixedAxis = 0x01,
  30.         Graph2FixedAxis = 0x02
  31.     };
  32. private:
  33.     QSerialPort *serialPort1;
  34.     QSerialPort *serialPort2;
  35. private slots:
  36.     void on_setBtn_clicked();
  37.     void on_exitBtn_clicked();
  38.     void on_Uart1Enable_clicked(bool checked);
  39.     void on_Uart2Enable_clicked(bool checked);
  40.     void uart1Recieve();
  41.     void uart2Recieve();
  42.     void realtimeDataSlot();
  43.     void showMainUi();
  44.     void on_searchBtn_clicked();
  45. protected:
  46.     void showEvent(QShowEvent *event) override;
  47.     void closeEvent(QCloseEvent *event) override;
  48.     //void paintEvent(QPaintEvent *event) override;
  49. private:
  50.     Ui::MainWindow *ui;
  51.     QSettings *config;
  52.     QCustomPlot *plot_1;
  53.     QCustomPlot *plot_2;
  54.     QTimer *dataTimer;
  55.     double key;  //用来记录横坐标的时间刻度
  56.     Setting *settingUi;
  57.     Search *searchUi;
  58.     quint8 isFixedAxisRange;
  59.     QSqlDatabase *database;
  60. };
  61. #endif // MAINWINDOW_H
复制代码
mainwindow.cpp 主界面源文件

  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3. #include <QMessageBox>
  4. #include <QDebug>
  5. MainWindow::MainWindow(QWidget *parent)
  6.     : QMainWindow(parent)
  7.     , ui(new Ui::MainWindow)
  8. {
  9.     //初始化各成员变量
  10.     settingUi = new Setting();
  11.     initDatabase(); //必须在实例化Search对象之前初始化数据库
  12.     searchUi = new Search(database);
  13.     ui->setupUi(this);
  14.     plot_1 = ui->customPlot1;
  15.     plot_2 = ui->customPlot2;
  16.     dataTimer = new QTimer(this);
  17.     //打开配置文件
  18.     config = new QSettings("config.ini", QSettings::IniFormat);
  19.     serialPort1 = new QSerialPort(this);
  20.     serialPort2 = new QSerialPort(this);
  21.     //连接串口接收槽函数
  22.     connect(serialPort1, SIGNAL(readyRead()), this, SLOT(uart1Recieve()));
  23.     connect(serialPort2, SIGNAL(readyRead()), this, SLOT(uart2Recieve()));
  24.     // 使上下轴、左右轴范围同步
  25.     connect(plot_2->xAxis, SIGNAL(rangeChanged(QCPRange)), plot_2->xAxis2, SLOT(setRange(QCPRange)));
  26.     connect(plot_2->yAxis, SIGNAL(rangeChanged(QCPRange)), plot_2->yAxis2, SLOT(setRange(QCPRange)));
  27.     //定时器连接槽函数realtimeDataSlot
  28.     connect(dataTimer, SIGNAL(timeout()), this, SLOT(realtimeDataSlot()));
  29.     //实现关闭设置界面/查询界面 显示主界面
  30.     connect(settingUi, SIGNAL(showMainUi()), this, SLOT(showMainUi()));
  31.     connect(searchUi, SIGNAL(showMainUi()), this, SLOT(showMainUi()));
  32.     //this->setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
  33.     initMainUi();
  34. }
  35. MainWindow::~MainWindow()
  36. {
  37.     delete ui;
  38. }
  39. void MainWindow::initMainUi()
  40. {
  41.     //串口数据显示区
  42.     //坐标轴使用时间
  43.     QSharedPointer<QCPAxisTickerTime> timeTicker(new QCPAxisTickerTime);
  44.     timeTicker->setTimeFormat("%h:%m:%s");
  45.     //设置曲线颜色(显示区域2)
  46.     plot_2->addGraph();
  47.     plot_2->graph(0)->setPen(QPen(QColor("#4fa08b"))); //测试数据
  48.     plot_2->addGraph();
  49.     plot_2->graph(1)->setPen(QPen(QColor(255, 100, 40))); //串口2
  50.     plot_2->xAxis->setTicker(timeTicker);
  51.     //四边安上坐标轴
  52.     plot_2->axisRect()->setupFullAxesBox();
  53.     //设置坐标轴名字
  54.     plot_2->xAxis->setLabel("时间/h:m:s");
  55.     plot_2->yAxis->setLabel("幅值");
  56.     //plot_2->setBackground(QBrush(QColor("#454545")));
  57.     //显示区域1
  58.     plot_1->addGraph();
  59.     plot_1->graph(0)->setPen(QPen(QColor("#4fa08b"))); //测试数据
  60.     plot_1->addGraph();
  61.     plot_1->graph(1)->setPen(QPen(QColor("#FFFF00"))); //串口1
  62.     plot_1->xAxis->setTicker(timeTicker);
  63.     plot_1->axisRect()->setupFullAxesBox();
  64.     plot_1->xAxis->setLabel("时间/h:m:s");
  65.     plot_1->yAxis->setLabel("幅值");
  66.     //设置plotstyle,与样式表相匹配
  67.     setCustomplotStyle("ManjaroMix", plot_1);
  68.     setCustomplotStyle("ManjaroMix", plot_2);
  69.     dataTimer->start(20); // 间隔时间 20ms表示刷新率为50hz
  70. }
  71. void MainWindow::setSerialPort(QSerialPort *serialPort)
  72. {
  73.     //这一段的作用是根据串口变量名选择不同配置组,配置相应串口参数
  74.     QString str = "ConfigData";
  75.     if (serialPort == serialPort1)
  76.         str = STR(serialPort1) + str;
  77.     else if (serialPort == serialPort2)
  78.         str = STR(serialPort2) + str;
  79.     //qDebug() << str <<endl;
  80.     this->config->beginGroup(str);
  81.     //设置串口名
  82.     serialPort->setPortName(this->config->value("serialName").toString());
  83.     //设置波特率
  84.     serialPort->setBaudRate(this->config->value("baudrate", 9600).toInt());
  85.     //设置校验位
  86.     switch(this->config->value("paritybit", 0).toInt())
  87.     {
  88.     case 0:
  89.         serialPort->setParity(QSerialPort::NoParity);
  90.         break;
  91.     case 1:
  92.         serialPort->setParity(QSerialPort::OddParity);
  93.         break;
  94.     case 2:
  95.         serialPort->setParity(QSerialPort::EvenParity);
  96.         break;
  97.     default:
  98.         break;
  99.     }
  100.     //设置停止位
  101.     switch(this->config->value("stopbit", 0).toInt())
  102.     {
  103.     case 0:
  104.         serialPort->setStopBits(QSerialPort::OneStop);
  105.         break;
  106.     case 1:
  107.         serialPort->setStopBits(QSerialPort::OneAndHalfStop);
  108.         break;
  109.     case 2:
  110.         serialPort->setStopBits(QSerialPort::TwoStop);
  111.         break;
  112.     default:
  113.         break;
  114.     }
  115.     //设置数据位
  116.     switch (this->config->value("databit", 8).toInt())
  117.     {
  118.     case 5:
  119.         serialPort->setDataBits(QSerialPort::Data5);
  120.         break;
  121.     case 6:
  122.         serialPort->setDataBits(QSerialPort::Data6);
  123.         break;
  124.     case 7:
  125.         serialPort->setDataBits(QSerialPort::Data7);
  126.         break;
  127.     case 8:
  128.         serialPort->setDataBits(QSerialPort::Data8);
  129.         break;
  130.     default:
  131.         break;
  132.     }
  133.     this->config->endGroup();
  134.     //设置流控为无流控
  135.     serialPort->setFlowControl(QSerialPort::NoFlowControl);
  136. }
  137. void MainWindow::initDatabase()
  138. {
  139.     database = new QSqlDatabase();
  140.     if (QSqlDatabase::contains("qt_sql_default_connection"))  //如果目录下已有数据库
  141.     {
  142.         *database = QSqlDatabase::database("qt_sql_default_connection");
  143.     }
  144.     else  //未有数据库则创建
  145.     {
  146.         *database = QSqlDatabase::addDatabase("QSQLITE");
  147.         database->setDatabaseName("MyDataBase.db");
  148.         database->setUserName("L");
  149.         database->setPassword("123456");
  150.     }
  151.     if (!database->open())
  152.     {
  153.         qDebug() << "Error: Failed to connect database." << database->lastError();
  154.         return;
  155.     }
  156.     QSqlQuery sql_query(*database);
  157.     //设置数据库表格式,以横坐标轴数据(X轴:时间s)为主键,包含图像id和Y轴数据,
  158.     //这里只演示了存储一条曲线的表格式,可以再添加图像id标识不同曲线,对应不同value值
  159.     QString create_sql = "create table graph (timecount double primary key, graphid int, value double);";
  160.     //sql_query.prepare(create_sql);
  161.     //QString tableExist = "select count(*) from sqlite_master where type='table' and name='graph';";
  162.     //创建表
  163.     sql_query.exec(create_sql);
  164.     sql_query.exec("delete from graph"); //清空表
  165.     //qDebug() << "Error: Fail to create table." << sql_query.lastError();
  166. }
  167. void MainWindow::setCustomplotStyle(const QString& style, QCustomPlot *plot)
  168. {
  169.     if (style == "ManjaroMix")
  170.     {
  171.         //坐标轴颜色
  172.         MainWindow::setAxisColor("#4fa08b", plot);
  173.         //背景颜色
  174.         plot->setBackground(QBrush("#353a3e"));
  175.     }
  176.     else if (style == "")  //根据自己需要配置相应主题颜色
  177.     {
  178.     }
  179. }
  180. void MainWindow::setAxisColor(const QString& color, QCustomPlot *plot)
  181. {
  182.     plot->xAxis->setLabelColor(QColor(color));
  183.     plot->xAxis->setTickLabelColor(QColor(color));
  184.     plot->xAxis->setTickPen(QPen(QColor(color)));
  185.     plot->xAxis->setSubTickPen(QPen(QColor(color)));
  186.     plot->xAxis->setBasePen(QPen(QColor(color)));
  187.     plot->yAxis->setLabelColor(QColor(color));
  188.     plot->yAxis->setTickLabelColor(QColor(color));
  189.     plot->yAxis->setTickPen(QPen(QColor(color)));
  190.     plot->yAxis->setSubTickPen(QPen(QColor(color)));
  191.     plot->yAxis->setBasePen(QPen(QColor(color)));
  192.     plot->xAxis2->setLabelColor(QColor(color));
  193.     plot->xAxis2->setTickLabelColor(QColor(color));
  194.     plot->xAxis2->setTickPen(QPen(QColor(color)));
  195.     plot->xAxis2->setSubTickPen(QPen(QColor(color)));
  196.     plot->xAxis2->setBasePen(QPen(QColor(color)));
  197.     plot->yAxis2->setLabelColor(QColor(color));
  198.     plot->yAxis2->setTickLabelColor(QColor(color));
  199.     plot->yAxis2->setTickPen(QPen(QColor(color)));
  200.     plot->yAxis2->setSubTickPen(QPen(QColor(color)));
  201.     plot->yAxis2->setBasePen(QPen(QColor(color)));
  202. }
  203. void MainWindow::on_setBtn_clicked()
  204. {
  205. #ifdef QT_DEBUG
  206.     settingUi->show();
  207. #else
  208.     settingUi->showFullScreen();
  209. #endif
  210.     QTime dieTime = QTime::currentTime().addMSecs(300);//延时300毫秒
  211.     while (QTime::currentTime() < dieTime)
  212.         QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
  213.     this->hide();
  214. }
  215. void MainWindow::on_exitBtn_clicked()
  216. {
  217.     this->close();
  218. }
  219. void MainWindow::showEvent(QShowEvent *event)
  220. {
  221.     //更新设置
  222.     isFixedAxisRange = 0;
  223.     //读取是否固定坐标轴参数
  224.     config->beginGroup("customPlot1ConfigData");
  225.     if (config->value("fixedRange", false).toBool())
  226.         isFixedAxisRange |= MainWindow::Graph1FixedAxis;
  227.     config->endGroup();
  228.     config->beginGroup("customPlot2ConfigData");
  229.     if (config->value("fixedRange", false).toBool())
  230.         isFixedAxisRange |= MainWindow::Graph2FixedAxis;
  231.     config->endGroup();
  232.     QMainWindow::showEvent(event);
  233. }
  234. void MainWindow::closeEvent(QCloseEvent *event)
  235. {
  236.     QMainWindow::closeEvent(event);
  237. }
  238. //打开串口1
  239. void MainWindow::on_Uart1Enable_clicked(bool checked)
  240. {
  241.     if (checked)
  242.     {
  243.         setSerialPort(serialPort1);
  244.         if(!serialPort1->open(QIODevice::ReadWrite))
  245.         {
  246.             QMessageBox::warning(this, "串口错误", "串口打开失败或串口被占用");
  247.             qDebug() << serialPort1->errorString() << endl;
  248.             qDebug() << serialPort1->portName() << endl;
  249.             ui->Uart1Enable->setChecked(false);
  250.             return;
  251.         }
  252.     }
  253.     else
  254.     {
  255.         serialPort1->close();
  256.     }
  257. }
  258. //打开串口2
  259. void MainWindow::on_Uart2Enable_clicked(bool checked)
  260. {
  261.     if (checked)
  262.     {
  263.         setSerialPort(serialPort2);
  264.         if(!serialPort2->open(QIODevice::ReadWrite))
  265.         {
  266.             QMessageBox::warning(this, "串口错误", "串口打开失败或串口被占用");
  267.             ui->Uart2Enable->setChecked(false);
  268.             return;
  269.         }
  270.     }
  271.     else
  272.     {
  273.         serialPort2->close();
  274.     }
  275. }
  276. //重绘函数
  277. void MainWindow::realtimeDataSlot()
  278. {
  279.     static QTime time(QTime::currentTime());
  280.     key = time.elapsed()/1000.0; // 开始到现在的时间,单位秒
  281.     static double lastPointKey = 0;
  282.     //数据库
  283.     QSqlQuery sql_query(*database);
  284.     if (key - lastPointKey > 0.002) // 大约20ms添加一次数据,这里其实跟刷新率也有关系,若刷新时间间隔大于该时间间隔则取决于刷新时间间隔
  285.     {
  286.         // 添加测试数据到graph
  287.         double value = qSin(key)+qrand()/(double)RAND_MAX*1*qSin(key/0.3843) * 80;
  288.         plot_2->graph(0)->addData(key, value);
  289.         sql_query.exec(QString("insert into graph values( '%1', 0, '%2')").arg(key).arg(value));  //将数据存储到数据库
  290.         //另一组测试数据,显示在另外一张坐标轴上但不存储
  291.         //plot_1->graph(0)->addData(key, (qCos(key)+qrand()/(double)RAND_MAX*0.5*qSin(key/0.4364)) * 70);
  292.         //记录当前时刻
  293.         lastPointKey = key;
  294.     }
  295.     // 曲线能动起来的关键在这里,设定x轴范围为最近30个时刻
  296.     // 这里设置图像从左边开始绘制,当绘制满整个界面时图像开始整体左移
  297.     if (key < 30)
  298.     {
  299.         plot_1->xAxis->setRange(0, 30, Qt::AlignLeft);
  300.         plot_2->xAxis->setRange(0, 30, Qt::AlignLeft);
  301.     }
  302.     else
  303.     {
  304.         plot_1->xAxis->setRange(key - 30, 30, Qt::AlignLeft);
  305.         plot_2->xAxis->setRange(key - 30, 30, Qt::AlignLeft);
  306.     }
  307.     //设置坐标轴是否固定范围,若是则从配置文件读取范围参数,否则自动调整y轴范围,ps:前面写配置文件的时候偷懒了,这里可以再优化一下让代码更简洁的
  308.     if (isFixedAxisRange == MainWindow::Graph1FixedAxis)
  309.     {
  310.         config->beginGroup("customPlot1ConfigData");
  311.         double ymin = config->value("ymin", -100).toDouble();
  312.         double ymax = config->value("ymax", 100).toDouble();
  313.         config->endGroup();
  314.         plot_1->yAxis->setRange(ymin, ymax);
  315.         plot_2->yAxis->rescale();
  316.     }
  317.     else if (isFixedAxisRange == MainWindow::Graph2FixedAxis)
  318.     {
  319.         config->beginGroup("customPlot2ConfigData");
  320.         double ymin = config->value("ymin", -100).toDouble();
  321.         double ymax = config->value("ymax", 100).toDouble();
  322.         config->endGroup();
  323.         plot_2->yAxis->setRange(ymin, ymax);
  324.         plot_1->yAxis->rescale();
  325.     }
  326.     else if (isFixedAxisRange == (MainWindow::Graph1FixedAxis | MainWindow::Graph2FixedAxis))
  327.     {
  328.         config->beginGroup("customPlot1ConfigData");
  329.         double ymin = config->value("ymin", -100).toDouble();
  330.         double ymax = config->value("ymax", 100).toDouble();
  331.         config->endGroup();
  332.         plot_1->yAxis->setRange(ymin, ymax);
  333.         config->beginGroup("customPlot2ConfigData");
  334.         ymin = config->value("ymin", -100).toDouble();
  335.         ymax = config->value("ymax", 100).toDouble();
  336.         config->endGroup();
  337.         plot_2->yAxis->setRange(ymin, ymax);
  338.     }
  339.     else  //两个显示区都自动调整坐标轴范围
  340.     {
  341.         plot_1->yAxis->rescale();
  342.         plot_2->yAxis->rescale();
  343.     }
  344.     //绘图
  345.     plot_2->replot();
  346.     plot_1->replot();
  347. }
  348. void MainWindow::showMainUi()
  349. {
  350. #ifdef QT_DEBUG
  351.     this->show();
  352. #else
  353.     this->showFullScreen();
  354. #endif
  355. }
  356. void MainWindow::uart1Recieve()
  357. {
  358.     ui->UartInfo_1->clear();
  359.     QByteArray buff = serialPort1->readAll();
  360.     //将串口数据实时显示
  361.     ui->UartInfo_1->setText(QString(buff));
  362.     //将串口接收的数据加到曲线中
  363.     plot_1->graph(1)->addData(key, buff.toInt());
  364. }
  365. void MainWindow::uart2Recieve()
  366. {
  367.     ui->UartInfo_2->clear();
  368.     QByteArray buff = serialPort2->readAll();
  369.     ui->UartInfo_2->setText(QString(buff));
  370.     plot_2->graph(1)->addData(key, buff.toInt());
  371. }
  372. void MainWindow::on_searchBtn_clicked()
  373. {
  374. #ifdef QT_DEBUG
  375.     searchUi->show();
  376. #else
  377.     searchUi->showFullScreen();
  378. #endif
  379.     //这一段代码的作用主要是:解决程序在低配置机器上运行时界面切换会闪烁的问题,这里的延时可以自己根据机器进行调整
  380.     QTime dieTime = QTime::currentTime().addMSecs(300);//延时300毫秒
  381.     while (QTime::currentTime() < dieTime)
  382.         QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
  383.     this->hide();
  384. }
复制代码
search.h 查询界面头文件

  1. #ifndef SEARCH_H
  2. #define SEARCH_H
  3. #include <QMainWindow>
  4. #include <QSqlDatabase>
  5. #include <QSqlError>
  6. #include <QSqlQuery>
  7. class  MainWindow;
  8. namespace Ui {
  9. class Search;
  10. }
  11. class Search : public QMainWindow
  12. {
  13.     Q_OBJECT
  14.     friend class MainWindow;
  15. public:
  16.     explicit Search(QSqlDatabase *db, QWidget *parent = nullptr);
  17.     ~Search();
  18.     int queryRowCount(QSqlQuery&);
  19.     //void initGraph
  20. private:
  21.     Ui::Search *ui;
  22.     QSqlDatabase *database;
  23. signals:
  24.     void showMainUi();
  25. private slots:
  26.     void on_searchBtn_clicked();
  27.     void on_backBtn_clicked();
  28.     void on_clearBtn_clicked();
  29. };
  30. #endif // SEARCH_H
复制代码
search.cpp 查询界面源文件

  1. #include "search.h"
  2. #include "ui_search.h"
  3. #include <QMessageBox>
  4. #include "mainwindow.h"
  5. Search::Search(QSqlDatabase *db, QWidget *parent) :
  6.     QMainWindow(parent),
  7.     ui(new Ui::Search)
  8. {
  9.     ui->setupUi(this);
  10.     database = db;
  11.     //坐标轴使用时间
  12.     QSharedPointer<QCPAxisTickerTime> timeTicker(new QCPAxisTickerTime);
  13.     timeTicker->setTimeFormat("%h:%m:%s");
  14.     ui->plot->xAxis->setTicker(timeTicker);
  15.     //四边安上坐标轴
  16.     ui->plot->axisRect()->setupFullAxesBox();
  17.     //设置坐标轴名字
  18.     ui->plot->xAxis->setLabel("时间/h:m:s");
  19.     ui->plot->yAxis->setLabel("幅值");
  20.     //ui->plot->graph(0)->rescaleAxes();
  21.     this->setWindowTitle(QString("查询窗口"));
  22.     //设置显示风格
  23.     MainWindow::setCustomplotStyle("ManjaroMix", ui->plot);
  24. }
  25. Search::~Search()
  26. {
  27.     delete ui;
  28. }
  29. //获取表格行数即数据个数
  30. int Search::queryRowCount(QSqlQuery & query)
  31. {
  32.     // 获取query指针首地址
  33.     int initialPos = query.at();
  34.     int pos = 0;
  35.     if (query.last()){
  36.         pos = query.at() + 1;
  37.     }else{
  38.         pos = 0;
  39.     }
  40.     // 计算行数后将query指针放到首地址
  41.     query.seek(initialPos);
  42.     return pos;
  43. }
  44. void Search::on_backBtn_clicked()
  45. {
  46.     emit showMainUi();
  47.     QTime dieTime = QTime::currentTime().addMSecs(300);//延时300毫秒
  48.     while (QTime::currentTime() < dieTime)
  49.         QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
  50.     this->close();
  51. }
  52. void Search::on_searchBtn_clicked()
  53. {
  54.     //输入数据检查
  55.     if (ui->bgTimeLEdt->text().toDouble() >= ui->edTimeLEdt->text().toDouble())
  56.     {
  57.         QMessageBox::warning(this, "warning", "时间输入错误!");
  58.         return;
  59.     }
  60.     //设置曲线颜色
  61.     ui->plot->addGraph();
  62.     ui->plot->graph(0)->setPen(QPen(QColor("#4fa08b"))); //测试数据
  63.     QSqlQuery sql_query(*database);
  64.     QString search = QString("select * from graph where graphid = '%1' and timecount >= '%2' and timecount <= '%3';")\
  65.             .arg(ui->graphidLEdt->text()).arg(ui->bgTimeLEdt->text()).arg(ui->edTimeLEdt->text());
  66.     //QString search("select * from graph where graphid = '%1' and timecount >= '%2' and timecount <= '%3';");
  67.     sql_query.exec(search);
  68.     while (sql_query.next())
  69.     {
  70.         double key = sql_query.value(0).toDouble();
  71.         double value = sql_query.value(2).toDouble();
  72.         ui->plot->graph(0)->addData(key, value);
  73.     }
  74.     ui->plot->yAxis->rescale();
  75.     ui->plot->xAxis->rescale();
  76.     ui->plot->replot();
  77.     //状态栏显示graph信息
  78.     this->statusBar()->showMessage(
  79.                 QString("曲线点数:%1")
  80.                 .arg(queryRowCount(sql_query)));
  81. }
  82. void Search::on_clearBtn_clicked()
  83. {
  84.     ui->plot->clearGraphs();    //删除所有graph
  85.     ui->plot->replot();         //重绘清屏
  86.     this->statusBar()->clearMessage();
  87. }
复制代码
setting.h 设置界面头文件

  1. #ifndef SETTING_H
  2. #define SETTING_H
  3. #include <QMainWindow>
  4. #include <QSettings>
  5. namespace Ui {
  6. class Setting;
  7. }
  8. class Setting : public QMainWindow
  9. {
  10.     Q_OBJECT
  11. public:
  12.     explicit Setting(QWidget *parent = nullptr);
  13.     ~Setting();
  14. private slots:
  15.     void on_backBtn_clicked();
  16.     void uartPortChanged(int);
  17.     void on_applyBtn_clicked();
  18. private:
  19.     Ui::Setting *ui;
  20.     QSettings *config;
  21. protected:
  22.     void showEvent(QShowEvent *event) override;
  23.     void closeEvent(QCloseEvent *event) override;
  24. signals:
  25.     void showMainUi();
  26. };
  27. #endif // SETTING_H
复制代码
setting.cpp 设置界面源文件

  1. #include "setting.h"
  2. #include "ui_setting.h"
  3. #include "ui_setting.h"
  4. #include "mainwindow.h"
  5. #include <QScreen>
  6. #include <QGuiApplication>
  7. #include <QDebug>
  8. #include <QSerialPort>
  9. #include <QSerialPortInfo>
  10. Setting::Setting(QWidget *parent) :
  11.     QMainWindow(parent),
  12.     ui(new Ui::Setting)
  13. {
  14.     ui->setupUi(this);
  15.     //打开配置文件
  16.     config = new QSettings("config.ini", QSettings::IniFormat);
  17.     //this->setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
  18.     //关联槽函数
  19.     connect(ui->buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(uartPortChanged(int)));
  20.     //connect(this, SIGNAL(showMainUi()), Widget, )
  21.     //扫描并显示串口名
  22.     foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
  23.     {
  24.         ui->serialName->addItem(info.portName());
  25.     }
  26. }
  27. Setting::~Setting()
  28. {
  29.     delete ui;
  30. }
  31. void Setting::on_backBtn_clicked()
  32. {
  33.     emit showMainUi();
  34.     QTime dieTime = QTime::currentTime().addMSecs(300);//延时300毫秒
  35.     while (QTime::currentTime() < dieTime)
  36.         QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
  37.     this->close();
  38. }
  39. void Setting::uartPortChanged(int id)
  40. {
  41.     Q_UNUSED(id);
  42.     QString str = ui->buttonGroup->checkedButton()->text();
  43.     if (str == "串口1")
  44.     {
  45.         //从配置文件读取串口1历史参数并显示
  46.         //qDebug() << "1" << endl;
  47.         config->beginGroup("serialPort1ConfigData");
  48.         ui->serialName->setCurrentText(config->value("serialName").toString());
  49.         ui->buadRate->setCurrentText(config->value("baudrate", 9600).toString());
  50.         ui->dataBit->setCurrentText(config->value("databit", 8).toString());
  51.         ui->stopBit->setCurrentIndex(config->value("stopbit", 0).toInt());
  52.         ui->parityBit->setCurrentIndex(config->value("paritybit", 0).toInt());
  53.         config->endGroup();
  54. #if 0        //存储串口1的参数
  55.         uart1->serialName = ui->serialName->currentText();
  56.         uart1->baudRate = ui->buadRate->currentText().toInt();
  57.         uart1->dataBit = ui->dataBit->currentText().toInt();
  58.         uart1->stopBit = ui->stopBit->currentText().toDouble();
  59.         uart1->parityBit = ui->parityBit->currentText();
  60. #endif
  61.     }
  62.     else if (str == "串口2")
  63.     {
  64.         //从配置文件读取串口2历史参数并显示
  65.         //qDebug() << "2" << endl;
  66.         config->beginGroup("serialPort2ConfigData");
  67.         ui->serialName->setCurrentText(config->value("serialName").toString());
  68.         ui->buadRate->setCurrentText(config->value("baudrate", 9600).toString());
  69.         ui->dataBit->setCurrentText(config->value("databit", 8).toString());
  70.         ui->stopBit->setCurrentIndex(config->value("stopbit", 0).toInt());
  71.         ui->parityBit->setCurrentIndex(config->value("paritybit", 0).toInt());
  72.         config->endGroup();
  73. #if 0        //存储串口2的参数
  74.         uart1->serialName = ui->serialName->currentText();
  75.         uart1->baudRate = ui->buadRate->currentText().toInt();
  76.         uart1->dataBit = ui->dataBit->currentText().toInt();
  77.         uart1->stopBit = ui->stopBit->currentText().toDouble();
  78.         uart1->parityBit = ui->parityBit->currentText();
  79. #endif
  80.     }
  81. }
  82. void Setting::showEvent(QShowEvent *event)
  83. {
  84.     //获取主屏幕
  85.     //QScreen* screen = QGuiApplication::primaryScreen();
  86.     // 设置窗口位置和大小,使窗口全屏显示
  87.     //setGeometry(screen->geometry());
  88.     config->beginGroup("serialPort1ConfigData");
  89.     ui->serialName->setCurrentText(config->value("serialName").toString());
  90.     ui->buadRate->setCurrentText(config->value("baudrate", 9600).toString());
  91.     ui->dataBit->setCurrentText(config->value("databit", 8).toString());
  92.     ui->stopBit->setCurrentIndex(config->value("stopbit", 0).toInt());
  93.     ui->parityBit->setCurrentIndex(config->value("paritybit", 0).toInt());
  94.     config->endGroup();
  95.     //坐标轴参数
  96.     config->beginGroup("customPlot1ConfigData");
  97.     ui->fixedAxisRangeCkbx_1->setChecked(config->value("fixedRange", false).toBool());
  98.     ui->cstmPlt1Ymin->setText(config->value("ymin").toString());
  99.     ui->cstmPlt1Ymax->setText(config->value("ymax").toString());
  100.     config->endGroup();
  101.     config->beginGroup("customPlot2ConfigData");
  102.     ui->fixedAxisRangeCkbx_2->setChecked(config->value("fixedRange", false).toBool());
  103.     ui->cstmPlt2Ymin->setText(config->value("ymin").toString());
  104.     ui->cstmPlt2Ymax->setText(config->value("ymax").toString());
  105.     config->endGroup();
  106.     QWidget::showEvent(event);
  107. }
  108. void Setting::closeEvent(QCloseEvent *event)
  109. {
  110.     QWidget::closeEvent(event);
  111. }
  112. void Setting::on_applyBtn_clicked()
  113. {
  114.     //将各配置参数更新到配置文件
  115.     //串口数据
  116.     QString str = ui->buttonGroup->checkedButton()->text();
  117.     if (str == "串口1")
  118.     {
  119.         config->beginGroup("serialPort1ConfigData");
  120.         config->setValue("serialName", ui->serialName->currentText());
  121.         config->setValue("baudrate",  ui->buadRate->currentText());
  122.         config->setValue("databit", ui->dataBit->currentText());
  123.         config->setValue("stopbit", ui->stopBit->currentIndex());
  124.         config->setValue("paritybit", ui->parityBit->currentIndex());
  125.         config->endGroup();
  126.     }
  127.     else if (str == "串口2")
  128.     {
  129.         config->beginGroup("serialPort2ConfigData");
  130.         config->setValue("serialName", ui->serialName->currentText());
  131.         config->setValue("baudrate",  ui->buadRate->currentText());
  132.         config->setValue("databit", ui->dataBit->currentText());
  133.         config->setValue("stopbit", ui->stopBit->currentIndex());
  134.         config->setValue("paritybit", ui->parityBit->currentIndex());
  135.         config->endGroup();
  136.     }
  137.     //customPlot区域显示坐标轴范围
  138.     //区域1
  139.     config->beginGroup("customPlot1ConfigData");
  140.     config->setValue("fixedRange", ui->fixedAxisRangeCkbx_1->isChecked());
  141.     config->setValue("ymin", ui->cstmPlt1Ymin->text().toDouble());
  142.     config->setValue("ymax", ui->cstmPlt1Ymax->text().toDouble());
  143.     config->endGroup();
  144.     //区域2
  145.     config->beginGroup("customPlot2ConfigData");
  146.     config->setValue("fixedRange", ui->fixedAxisRangeCkbx_2->isChecked());
  147.     config->setValue("ymin", ui->cstmPlt2Ymin->text().toDouble());
  148.     config->setValue("ymax", ui->cstmPlt2Ymax->text().toDouble());
  149.     config->endGroup();
  150. }
复制代码
后续

        写到这里的时间间隔我创建这篇草稿已颠末去了大概五六个月,中央因为工作比较忙就没有再写下去,后续再次想要拿起QT的时间才想起来这篇草稿还没发,基本框架实在写得差不多了,而工程文件已经找不到了,如果后续我能找到就放上来,各人可以参考一下代码如何实现。这个项目属于初学者练手项目,另有诸多不敷,欢迎各人评论区讨论。





免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

万有斥力

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表