├── .gitignore
├── Alien 2.ico
├── Icons
├── Alien 2.png
└── gtk-help.png
├── README.md
├── Serial_Oscilloscope.pro
├── Serial_Oscilloscope.pro.user
├── icon.rc
├── main.cpp
├── mainwindow.cpp
├── mainwindow.h
├── mainwindow.ui
├── myresource.qrc
├── qcustomplot.cpp
└── qcustomplot.h
/.gitignore:
--------------------------------------------------------------------------------
1 | #release
2 | release/*
3 |
4 | # Prerequisites
5 | *.d
6 |
7 | # Compiled Object files
8 | *.slo
9 | *.lo
10 | *.o
11 | *.obj
12 |
13 | # Precompiled Headers
14 | *.gch
15 | *.pch
16 |
17 | # Compiled Dynamic libraries
18 | *.so
19 | *.dylib
20 | *.dll
21 |
22 | # Fortran module files
23 | *.mod
24 | *.smod
25 |
26 | # Compiled Static libraries
27 | *.lai
28 | *.la
29 | *.a
30 | *.lib
31 |
32 | # Executables
33 | *.exe
34 | *.out
35 | *.app
36 |
--------------------------------------------------------------------------------
/Alien 2.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Miller-em/UART_Oscillscope/bfb9982cc880b654990c90ee6659ac95af8219b5/Alien 2.ico
--------------------------------------------------------------------------------
/Icons/Alien 2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Miller-em/UART_Oscillscope/bfb9982cc880b654990c90ee6659ac95af8219b5/Icons/Alien 2.png
--------------------------------------------------------------------------------
/Icons/gtk-help.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Miller-em/UART_Oscillscope/bfb9982cc880b654990c90ee6659ac95af8219b5/Icons/gtk-help.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # UART_Oscillscope
2 |
3 |
4 |
5 | In order to facilitate the viewing of the data collected by the ADC of the microcontroller, and to be able to visualize the data. So use Qt to develop a software that can visualize the serial port data. At the same time, it also supports the sending of PID data, which is more convenient for debugging.
6 |
7 |
8 |
9 | ## User Interface
10 |
11 | 
--------------------------------------------------------------------------------
/Serial_Oscilloscope.pro:
--------------------------------------------------------------------------------
1 | QT += core gui serialport charts
2 |
3 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
4 |
5 | CONFIG += c++11
6 |
7 | RC_FILE = icon.rc
8 |
9 | # The following define makes your compiler emit warnings if you use
10 | # any Qt feature that has been marked deprecated (the exact warnings
11 | # depend on your compiler). Please consult the documentation of the
12 | # deprecated API in order to know how to port your code away from it.
13 | DEFINES += QT_DEPRECATED_WARNINGS
14 |
15 | # You can also make your code fail to compile if it uses deprecated APIs.
16 | # In order to do so, uncomment the following line.
17 | # You can also select to disable deprecated APIs only up to a certain version of Qt.
18 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
19 |
20 | SOURCES += \
21 | main.cpp \
22 | mainwindow.cpp \
23 | qcustomplot.cpp
24 |
25 | HEADERS += \
26 | mainwindow.h \
27 | qcustomplot.h
28 |
29 | FORMS += \
30 | mainwindow.ui
31 |
32 |
33 | # Default rules for deployment.
34 | qnx: target.path = /tmp/$${TARGET}/bin
35 | else: unix:!android: target.path = /opt/$${TARGET}/bin
36 | !isEmpty(target.path): INSTALLS += target
37 |
38 | RESOURCES += \
39 | myresource.qrc
40 |
41 | DISTFILES += \
42 | icon.rc
43 |
--------------------------------------------------------------------------------
/Serial_Oscilloscope.pro.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | EnvironmentId
7 | {7a4af49b-5b15-4c7a-b176-7ed7a738cb2c}
8 |
9 |
10 | ProjectExplorer.Project.ActiveTarget
11 | 0
12 |
13 |
14 | ProjectExplorer.Project.EditorSettings
15 |
16 | true
17 | false
18 | true
19 |
20 | Cpp
21 |
22 | CppGlobal
23 |
24 |
25 |
26 | QmlJS
27 |
28 | QmlJSGlobal
29 |
30 |
31 | 2
32 | UTF-8
33 | false
34 | 4
35 | false
36 | 80
37 | true
38 | true
39 | 1
40 | true
41 | false
42 | 0
43 | true
44 | true
45 | 0
46 | 8
47 | true
48 | 1
49 | true
50 | true
51 | true
52 | false
53 |
54 |
55 |
56 | ProjectExplorer.Project.PluginSettings
57 |
58 |
59 | -fno-delayed-template-parsing
60 |
61 | false
62 | {4ca48680-40b5-4f3b-beee-126f4d282b42}
63 |
64 |
65 |
66 | ProjectExplorer.Project.Target.0
67 |
68 | Desktop (x86-windows-msys-pe-64bit)
69 | Desktop (x86-windows-msys-pe-64bit)
70 | {0f665f2f-234f-4193-881c-c68d44f17e04}
71 | 1
72 | 0
73 | 0
74 |
75 | E:/Qt Develop/build-Serial_Oscilloscope-Quick_Demo-Debug
76 |
77 |
78 | true
79 | QtProjectManager.QMakeBuildStep
80 | true
81 |
82 | false
83 | false
84 | false
85 |
86 |
87 | true
88 | Qt4ProjectManager.MakeStep
89 |
90 | false
91 |
92 |
93 | false
94 |
95 | 2
96 | Build
97 | Build
98 | ProjectExplorer.BuildSteps.Build
99 |
100 |
101 |
102 | true
103 | Qt4ProjectManager.MakeStep
104 |
105 | true
106 | clean
107 |
108 | false
109 |
110 | 1
111 | Clean
112 | Clean
113 | ProjectExplorer.BuildSteps.Clean
114 |
115 | 2
116 | false
117 |
118 | Debug
119 | Qt4ProjectManager.Qt4BuildConfiguration
120 | 2
121 |
122 |
123 | E:/Qt Develop/Serial_Oscilloscope/release
124 |
125 |
126 | true
127 | QtProjectManager.QMakeBuildStep
128 | false
129 |
130 | false
131 | false
132 | true
133 |
134 |
135 | true
136 | Qt4ProjectManager.MakeStep
137 |
138 | false
139 |
140 |
141 | false
142 |
143 | 2
144 | Build
145 | Build
146 | ProjectExplorer.BuildSteps.Build
147 |
148 |
149 |
150 | true
151 | Qt4ProjectManager.MakeStep
152 |
153 | true
154 | clean
155 |
156 | false
157 |
158 | 1
159 | Clean
160 | Clean
161 | ProjectExplorer.BuildSteps.Clean
162 |
163 | 2
164 | false
165 |
166 | Release
167 | Qt4ProjectManager.Qt4BuildConfiguration
168 | 0
169 |
170 |
171 | E:/Qt Develop/build-Serial_Oscilloscope-Quick_Demo-Profile
172 |
173 |
174 | true
175 | QtProjectManager.QMakeBuildStep
176 | true
177 |
178 | false
179 | true
180 | true
181 |
182 |
183 | true
184 | Qt4ProjectManager.MakeStep
185 |
186 | false
187 |
188 |
189 | false
190 |
191 | 2
192 | Build
193 | Build
194 | ProjectExplorer.BuildSteps.Build
195 |
196 |
197 |
198 | true
199 | Qt4ProjectManager.MakeStep
200 |
201 | true
202 | clean
203 |
204 | false
205 |
206 | 1
207 | Clean
208 | Clean
209 | ProjectExplorer.BuildSteps.Clean
210 |
211 | 2
212 | false
213 |
214 | Profile
215 | Qt4ProjectManager.Qt4BuildConfiguration
216 | 0
217 |
218 | 3
219 |
220 |
221 | 0
222 | Deploy
223 | Deploy
224 | ProjectExplorer.BuildSteps.Deploy
225 |
226 | 1
227 | ProjectExplorer.DefaultDeployConfiguration
228 |
229 | 1
230 |
231 |
232 | dwarf
233 |
234 | cpu-cycles
235 |
236 |
237 | 250
238 |
239 | -e
240 | cpu-cycles
241 | --call-graph
242 | dwarf,4096
243 | -F
244 | 250
245 |
246 | -F
247 | true
248 | 4096
249 | false
250 | false
251 | 1000
252 |
253 | true
254 |
255 | false
256 | false
257 | false
258 | false
259 | true
260 | 0.01
261 | 10
262 | true
263 | kcachegrind
264 | 1
265 | 25
266 |
267 | 1
268 | true
269 | false
270 | true
271 | valgrind
272 |
273 | 0
274 | 1
275 | 2
276 | 3
277 | 4
278 | 5
279 | 6
280 | 7
281 | 8
282 | 9
283 | 10
284 | 11
285 | 12
286 | 13
287 | 14
288 |
289 | 2
290 |
291 | Qt4ProjectManager.Qt4RunConfiguration:E:/Qt Develop/Serial_Oscilloscope/Serial_Oscilloscope.pro
292 | E:/Qt Develop/Serial_Oscilloscope/Serial_Oscilloscope.pro
293 |
294 | false
295 |
296 | false
297 | true
298 | true
299 | false
300 | false
301 | true
302 |
303 | E:/Qt Develop/Serial_Oscilloscope/release
304 |
305 | 1
306 |
307 |
308 |
309 | ProjectExplorer.Project.TargetCount
310 | 1
311 |
312 |
313 | ProjectExplorer.Project.Updater.FileVersion
314 | 22
315 |
316 |
317 | Version
318 | 22
319 |
320 |
321 |
--------------------------------------------------------------------------------
/icon.rc:
--------------------------------------------------------------------------------
1 | IDI_ICON1 ICON "Alien 2.ico"
--------------------------------------------------------------------------------
/main.cpp:
--------------------------------------------------------------------------------
1 | #include "mainwindow.h"
2 |
3 | #include
4 |
5 | int main(int argc, char *argv[])
6 | {
7 | QApplication a(argc, argv);
8 | MainWindow w;
9 | w.show();
10 | return a.exec();
11 | }
12 |
--------------------------------------------------------------------------------
/mainwindow.cpp:
--------------------------------------------------------------------------------
1 | #include "mainwindow.h"
2 | #include "ui_mainwindow.h"
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | const int color[10]={
16 | 0xff0000,0xffff00,0x00ff00,0x0000ff,0xff00ff,
17 | 0xff8000,0xc0ff00,0x00ffff,0x8000ff,0x000001,
18 | };
19 |
20 | MainWindow::MainWindow(QWidget *parent)
21 | : QMainWindow(parent)
22 | , ui(new Ui::MainWindow)
23 | {
24 | ui->setupUi(this);
25 | this->setWindowIcon(QIcon(":/Images/Icons/Alien 2.png"));
26 | this->setWindowTitle(tr("串口示波器"));
27 | ui->baudRate->setCurrentIndex(1);
28 | this->system_init(); //系统各组件初始化
29 | }
30 |
31 | MainWindow::~MainWindow()
32 | {
33 | delete ui;
34 | }
35 |
36 | /*-----------------------------------------------------------
37 | * functions
38 | * ----------------------------------------------------------*/
39 |
40 | void MainWindow::system_init()
41 | {
42 | // 这是statusbar的相关初始化
43 | QLabel *permanent = new QLabel(this);
44 | permanent->setFrameStyle(QFrame::Box | QFrame::Sunken);
45 | permanent->setText(
46 | tr("xiaozhoua.top"));
47 | permanent->setTextFormat(Qt::RichText);
48 | permanent->setOpenExternalLinks(true);
49 | ui->statusbar->addPermanentWidget(permanent);
50 | statusLabel = new QLabel;
51 | statusLabel->setMinimumSize(150, 20); // 设置标签最小大小
52 | statusLabel->setFrameShape(QFrame::WinPanel); // 设置标签形状
53 | statusLabel->setFrameShadow(QFrame::Sunken); // 设置标签阴影
54 | ui->statusbar->addWidget(statusLabel);
55 | statusLabel->setText(tr("所属人:Xiaozhoua"));
56 | statusLabel->setStyleSheet("color: white");
57 | statusBar()->setStyleSheet("background-color : rgb(30,30,30)");
58 |
59 | //PID 控制初始值控制
60 | ui->lineEdit->setText(tr("0"));
61 | ui->lineEdit_2->setText(tr("0"));
62 | ui->lineEdit_3->setText(tr("0"));
63 | ui->lineEdit_4->setText(tr("0"));
64 |
65 | // 串口初始化配置
66 | global_port.setParity(QSerialPort::NoParity); //无奇偶校验位
67 | global_port.setDataBits(QSerialPort::Data8); //8位校验位
68 | global_port.setStopBits(QSerialPort::OneStop); //停止位为1
69 | global_port.setFlowControl(QSerialPort::NoFlowControl); //无流控制
70 | connect(&global_port, SIGNAL(readyRead()), this, SLOT(receiveInfo()));
71 |
72 | // 示波器初始化配置
73 | ui->customPlot->setBackground(QBrush(QColor("#474848")));
74 | }
75 |
76 | QStringList MainWindow::getPortNameList()
77 | {
78 | /*--------------------------------
79 | * 获取系统串口信息
80 | *-------------------------------*/
81 | QStringList m_serialPortName;
82 | foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
83 | {
84 | m_serialPortName << info.portName();
85 | qDebug()<<"serialPortName:"<customPlot->setBackground(QBrush(QColor("#000000")));
90 | void MainWindow::buildChart()
91 | {
92 | /*--------------------------------
93 | * 构造示波器
94 | *-------------------------------*/
95 | ui->customPlot->setBackground(QBrush(QColor("#474848")));
96 | ui->customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); //可拖拽+可滚轮缩放
97 |
98 | ui->customPlot->axisRect()->setupFullAxesBox();
99 | ui->customPlot->yAxis->setRange(0, 3.3);
100 | }
101 |
102 | void MainWindow::plotCustom(QByteArray info)
103 | {
104 | //避免中文乱码
105 | QTextCodec *tc = QTextCodec::codecForName("GBK");
106 | QString tmpQStr = tc->toUnicode(info);
107 |
108 | // 若示波器打开,开始解析数据
109 | if (oscill_flag){
110 | QStringList datakeys;
111 |
112 | QJsonParseError jsonError;
113 | QJsonDocument jsonDoc = QJsonDocument::fromJson(info, &jsonError);
114 |
115 | if (jsonError.error != QJsonParseError::NoError)
116 | {
117 | qDebug() << "parse json object failed, " << jsonError.errorString();
118 | ui->textBrowser->append("parse json object failed!");
119 | return;
120 | }
121 | QJsonObject jsonObj = jsonDoc.object();
122 |
123 | qDebug() << "parse json object Successfully";
124 | datakeys = jsonObj.keys(); // 获取通道名称
125 | qDebug() << datakeys;
126 |
127 | if (Received_Keys != datakeys){
128 | // 只能够设置一次标签
129 | qDebug() << "update keys";
130 | Received_Keys = datakeys;
131 |
132 | this->index = 0;
133 | this->Ptext.clear();
134 | this->XData.clear();
135 | this->YData.clear();
136 | // 清除画布
137 | ui->customPlot->clearGraphs();
138 | ui->customPlot->legend->setVisible(false);
139 | ui->customPlot->replot();
140 |
141 | ui->customPlot->legend->setVisible(true); //右上角指示曲线的缩略框
142 | ui->customPlot->legend->setBrush(QColor(100, 100, 100, 0));//设置图例背景颜色,可设置透明
143 | ui->customPlot->legend->setTextColor(Qt::white);
144 | for (int i=0; i < datakeys.size(); i++){
145 | ui->customPlot->addGraph();
146 | ui->customPlot->graph(i)->setPen(QPen(color[i]));
147 | ui->customPlot->graph(i)->setName(datakeys[i]);
148 | Ptext.push_back(datakeys[i]);
149 | }
150 | }
151 |
152 | // 添加XData , YData 数据
153 | XData.push_back(index);
154 | QVector Data;
155 | YData.resize(datakeys.size());
156 |
157 | for (int i = 0; i < Ptext.size(); ++i) {
158 | Data.push_back(jsonObj.value(datakeys[i]).toDouble());
159 | }
160 | for (int i = 0; i < Ptext.size(); ++i) {
161 | YData[i].push_back(Data[i]);
162 | }
163 |
164 | //向坐标值赋值
165 | for (int i=0; i < datakeys.size(); ++i){
166 | ui->customPlot->graph(i)->addData(XData[index], YData[i][index]);
167 | }
168 | this->index++;
169 | // 更新坐标
170 | ui->customPlot->xAxis->setRange((ui->customPlot->graph(0)->dataCount()>1000)?
171 | (ui->customPlot->graph(0)->dataCount()-1000):
172 | 0,
173 | ui->customPlot->graph(0)->dataCount());
174 | ui->customPlot->replot(QCustomPlot::rpQueuedReplot); //实现重绘
175 | }
176 | // 向接收区打印
177 | ui->textBrowser->append(tmpQStr);
178 | qDebug() << "Received Data: " << tmpQStr;
179 | }
180 | /*-----------------------------------------------------------
181 | * slots
182 | * ----------------------------------------------------------*/
183 |
184 | void MainWindow::on_OpenorClose_clicked()
185 | {
186 | /*--------------------------------
187 | * 打开或者关闭串口
188 | *-------------------------------*/
189 | if (!this->OpenorClose_Flag){
190 | // 打开串口
191 | ui->OpenorClose->setText("关闭串口");
192 | this->OpenorClose_Flag = true;
193 |
194 | //设置串口端口
195 | QStringList m_serialPortName;
196 | m_serialPortName = getPortNameList(); //配置
197 | qDebug()<portId->clear();
199 | ui->portId->addItems(m_serialPortName);
200 |
201 | //Serial 配置
202 |
203 | QString portId;
204 | portId = ui->portId->currentText();
205 | qDebug() << "portId: " << portId;
206 | global_port.setPortName(portId); //配置端口号
207 |
208 | QString baudRate;
209 | baudRate = ui->baudRate->currentText();
210 | qDebug() << "baudRate: " << baudRate;
211 | global_port.setBaudRate(baudRate.toInt(), QSerialPort::AllDirections); //配置波特率
212 |
213 | // 配置完成,开启串口
214 | global_port.open(QIODevice::ReadWrite);
215 | qDebug() << "Open Serial Successfully";
216 | }else{
217 | // 关闭串口
218 | global_port.close();
219 | qDebug() << "Close Serial Successfully";
220 | ui->OpenorClose->setText("打开串口");
221 | this->OpenorClose_Flag = false;
222 | }
223 | }
224 |
225 | void MainWindow::on_sendPIDData_clicked()
226 | {
227 | /*--------------------------------
228 | * 发送PID相关数据
229 | *-------------------------------*/
230 | if (global_port.isOpen()){
231 | QString P, I, D, targetVal;
232 | QJsonObject sendPIDData;
233 |
234 | P = ui->lineEdit->text();
235 | I = ui->lineEdit_2->text();
236 | D = ui->lineEdit_3->text();
237 | targetVal = ui->lineEdit_4->text();
238 | sendPIDData.insert("P", P.toFloat());
239 | sendPIDData.insert("I", I.toFloat());
240 | sendPIDData.insert("D", D.toFloat());
241 | sendPIDData.insert("Target", targetVal.toFloat());
242 | QJsonDocument document;
243 | document.setObject(sendPIDData);
244 | QByteArray pidbyte_array = document.toJson(QJsonDocument::Compact);
245 | QString pidjson_str(pidbyte_array);
246 | pidjson_str += '\n';
247 | qDebug() << QString::fromLocal8Bit("PID Data:") << pidjson_str;
248 | global_port.write(pidjson_str.toLocal8Bit());
249 | }else{
250 | QMessageBox box;
251 | box.setWindowTitle(tr("警告"));
252 | box.setWindowIcon(QIcon(":/Images/Icons/Alien 2.png"));
253 | box.setIcon(QMessageBox::Warning);
254 | box.setText(tr(" 未检测到串口,请确认串口是否打开?"));
255 | box.exec();
256 | }
257 | }
258 |
259 | void MainWindow::on_sendData_clicked()
260 | {
261 | /*--------------------------------
262 | * 发送串口数据
263 | *-------------------------------*/
264 | if (global_port.isOpen()){
265 | QString sendData;
266 |
267 | sendData = ui->textEdit->toPlainText() + '\n';
268 | qDebug() << sendData;
269 | ui->textEdit->clear();
270 | global_port.write(sendData.toLocal8Bit());
271 | }else{
272 | QMessageBox box;
273 | box.setWindowTitle(tr("警告"));
274 | box.setWindowIcon(QIcon(":/Images/Icons/Alien 2.png"));
275 | box.setIcon(QMessageBox::Warning);
276 | box.setText(tr(" 未检测到串口,请确认串口是否打开?"));
277 | box.exec();
278 | }
279 | }
280 |
281 | void MainWindow::on_viewManual_clicked()
282 | {
283 | /*--------------------------------
284 | * 查看帮助手册
285 | *-------------------------------*/
286 | QString strtext="1.串口通讯格式:用Json数据格式进行传输。发送数据的字符串不得超过45个字符,否则漏失数据较为严重\n"
287 | "2.下位机MCU使用cJson进行发送数据\n"
288 | "3.暂停示波器,看波形目前只支持开关串口,但这样会造成丢失数据\n"
289 | "4.下位机发送字符串格式为: {\"xxx\":%.3f,\"xxx\":%.3f}";
290 | QMessageBox::information(this, "帮助信息", strtext, QMessageBox::Ok);
291 | }
292 |
293 | void MainWindow::on_pushButton_clicked()
294 | {
295 | /*--------------------------------
296 | * 清空PID相关数据
297 | *-------------------------------*/
298 | ui->lineEdit->setText(tr("0"));
299 | ui->lineEdit_2->setText(tr("0"));
300 | ui->lineEdit_3->setText(tr("0"));
301 | ui->lineEdit_4->setText(tr("0"));
302 | }
303 |
304 | void MainWindow::on_openOscill_clicked()
305 | {
306 | /*--------------------------------
307 | * 打开示波器
308 | *-------------------------------*/
309 | if (!oscill_flag){
310 | if (global_port.isOpen()){
311 | oscill_flag = true;
312 | buildChart();
313 | ui->openOscill->setText("关闭示波器");
314 | }else{
315 | QMessageBox box;
316 | box.setWindowTitle(tr("警告"));
317 | box.setWindowIcon(QIcon(":/Images/Icons/Alien 2.png"));
318 | box.setIcon(QMessageBox::Warning);
319 | box.setText(tr(" 未检测到串口,请确认串口是否打开?"));
320 | box.exec();
321 | }
322 | }else{
323 | // 置空所有状态值
324 | oscill_flag = false;
325 | this->index = 0;
326 | this->Ptext.clear();
327 | this->XData.clear();
328 | this->YData.clear();
329 | this->Received_Keys.clear();
330 | // 清楚画布
331 | ui->customPlot->clearGraphs();
332 | ui->customPlot->legend->setVisible(false);
333 | ui->customPlot->replot();
334 | ui->customPlot->setBackground(QBrush(QColor("#474848")));
335 | ui->openOscill->setText("打开示波器");
336 | }
337 | }
338 |
339 | void MainWindow::receiveInfo()
340 | {
341 | /*--------------------------------
342 | * 接受串口信息
343 | *-------------------------------*/
344 | QString data;
345 | QByteArray info = global_port.readAll();
346 | QStringList list;
347 |
348 | if(!info.isEmpty())
349 | {
350 | if (info.contains('{')){
351 | data = info;
352 | list= data.split("{");
353 | if (list.length() == 2){
354 | if (frontData.isEmpty()){
355 | frontData = list.at(1);
356 | frontData.insert(0,'{');
357 | return;
358 | }
359 | oneData = frontData + list.at(0);
360 | frontData = list.at(1);
361 | frontData.insert(0,'{');
362 | plotCustom(oneData.toLocal8Bit()); //绘图
363 | qDebug() << "One data: " << oneData;
364 | }
365 |
366 | if (list.length() == 3){
367 | oneData = frontData + list.at(0);
368 | plotCustom(oneData.toLocal8Bit()); //绘图
369 | qDebug() << "One data: " << oneData;
370 | oneData = list.at(1);
371 | oneData.insert(0,'{');
372 | plotCustom(oneData.toLocal8Bit()); //绘图
373 | qDebug() << "One data: " << oneData;
374 | frontData = list.at(2);
375 | frontData.insert(0,'{');
376 | }
377 | }
378 | }
379 | }
380 |
381 | void MainWindow::on_clearReceived_clicked()
382 | {
383 | /*--------------------------------
384 | * 清空接收区
385 | *-------------------------------*/
386 | ui->textBrowser->clear();
387 | }
388 |
389 | void MainWindow::on_stopOscill_clicked()
390 | {
391 | /*--------------------------------
392 | * 坐标轴缩放
393 | *-------------------------------*/
394 | if (stop_flag){
395 | ui->customPlot->axisRect()->setRangeZoom(Qt::Vertical);
396 | stop_flag = false;
397 | ui->stopOscill->setText("水平缩放");
398 | }else{
399 | ui->customPlot->axisRect()->setRangeZoom(Qt::Horizontal);
400 | stop_flag = true;
401 | ui->stopOscill->setText("垂直缩放");
402 | }
403 | }
404 |
--------------------------------------------------------------------------------
/mainwindow.h:
--------------------------------------------------------------------------------
1 | #ifndef MAINWINDOW_H
2 | #define MAINWINDOW_H
3 |
4 | #include
5 |
6 | /*-------------include----------------*/
7 | #include
8 | #include
9 | #include "qcustomplot.h"
10 | //#include
11 |
12 | /*-------------class------------------*/
13 | class QLabel;
14 | class QString;
15 | class QTimer;
16 | class QDebug;
17 |
18 | /*-------------define-----------------*/
19 | #define cout qDebug() << "[" << __FILE__ << ":" << __LINE__ << "]"
20 |
21 | /*-------------namespace--------------*/
22 | //using namespace QtCharts;
23 | QT_BEGIN_NAMESPACE
24 | namespace Ui { class MainWindow; }
25 | QT_END_NAMESPACE
26 |
27 |
28 | class MainWindow : public QMainWindow
29 | {
30 | Q_OBJECT
31 |
32 | public:
33 | MainWindow(QWidget *parent = nullptr);
34 | ~MainWindow();
35 |
36 | void buildChart(); //创建图表函数
37 | void plotCustom(QByteArray info);
38 |
39 | private slots:
40 | void on_OpenorClose_clicked();
41 |
42 | void on_sendPIDData_clicked();
43 |
44 | void on_sendData_clicked();
45 |
46 | void on_viewManual_clicked();
47 |
48 | void on_pushButton_clicked();
49 |
50 | void on_openOscill_clicked();
51 |
52 | void receiveInfo();
53 |
54 | void on_clearReceived_clicked();
55 |
56 | void on_stopOscill_clicked();
57 |
58 | private:
59 | Ui::MainWindow *ui;
60 |
61 | /*-------------function----------------*/
62 | void system_init();
63 | QStringList getPortNameList();
64 |
65 | /*-------------variable----------------*/
66 | // 串口声明
67 | QSerialPort global_port;
68 | // 状态栏声明
69 | QLabel *statusLabel;
70 | QLabel *msgLabel;
71 |
72 | // 串口相关
73 | QString receivedDdata = "";
74 | bool receivedFlag = false;
75 | bool OpenorClose_Flag = false;
76 | bool stop_flag = true;
77 |
78 | // 示波器相关
79 | bool oscill_flag = false;
80 | QVector Ptext; // 每条曲线上的显示的文字
81 | QVector > YData; // Y轴数据,可具有多个数据曲线
82 | QVector XData; // x轴数据
83 | double index = 0; // 索引
84 | QString frontData;
85 | QString backData;
86 | QString oneData;
87 | QStringList Received_Keys; // 标签值
88 | };
89 | #endif // MAINWINDOW_H
90 |
--------------------------------------------------------------------------------
/mainwindow.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | MainWindow
4 |
5 |
6 |
7 | 0
8 | 0
9 | 859
10 | 584
11 |
12 |
13 |
14 |
15 | 黑体
16 | 11
17 |
18 |
19 |
20 | MainWindow
21 |
22 |
23 |
24 | QWidget#centralwidget{
25 | background:rgb(30, 30, 30);
26 | }
27 |
28 |
29 |
30 | 0
31 |
32 |
33 | QLayout::SetDefaultConstraint
34 |
35 | -
36 |
37 |
38 | QFrame{
39 | color:rgb(60, 60, 60);
40 | background:rgb(30,30,30);
41 | border-top:1px solid darkGray;
42 | border-bottom:1px solid darkGray;
43 | border-right:1px solid darkGray;
44 | border-left:1px solid darkGray;
45 | border-top-right-radius:5px;
46 | border-bottom-right-radius:5px;
47 | border-top-left-radius:5px;
48 | border-bottom-left-radius:5px;
49 | }
50 | QLabel{
51 | border:none;
52 | color:white;
53 | font-size:16px;
54 | font-weight:700;
55 | font-family: "微软雅黑";
56 | }
57 |
58 |
59 |
-
60 |
61 |
62 | QPushButton{
63 | color:white;
64 | background:rgb(50,50,50); ;
65 | border-radius:3px;
66 | font-size:15px;
67 | font-weight:700;
68 | font-family: "微软雅黑";
69 | }
70 | QPushButton:hover{
71 | color:rgb(42,105,192);
72 | font-size:15px;
73 | font-weight:700;
74 | }
75 |
76 |
77 | QFrame::StyledPanel
78 |
79 |
80 | QFrame::Raised
81 |
82 |
83 |
-
84 |
85 |
86 | 查看使用说明
87 |
88 |
89 |
90 |
91 |
92 |
93 | -
94 |
95 |
96 | QFrame#frame{
97 | color:rgb(60, 60, 60);
98 | background:rgb(30,30,30);
99 | border-top:1px solid darkGray;
100 | border-bottom:1px solid darkGray;
101 | border-right:1px solid darkGray;
102 | border-left:1px solid darkGray;
103 | border-top-right-radius:5px;
104 | border-bottom-right-radius:5px;
105 | border-top-left-radius:5px;
106 | border-bottom-left-radius:5px;
107 | }
108 |
109 | QComboBox{
110 | font-size:12px;
111 | font-weight:700;
112 | font-family: "微软雅黑";
113 | }
114 |
115 | QPushButton{
116 | color:white;
117 | background:rgb(50,50,50); ;
118 | border-radius:3px;
119 | font-size:15px;
120 | font-weight:700;
121 | font-family: "微软雅黑";
122 | }
123 | QPushButton:hover{
124 | color:rgb(42,105,192);
125 | font-size:15px;
126 | font-weight:700;
127 | }
128 |
129 |
130 |
131 | QFrame::StyledPanel
132 |
133 |
134 | QFrame::Raised
135 |
136 |
137 |
-
138 |
139 |
-
140 |
141 |
142 |
143 | 微软雅黑
144 | -1
145 | 87
146 | true
147 |
148 |
149 |
150 | 操作:
151 |
152 |
153 |
154 | -
155 |
156 |
157 |
158 | 微软雅黑
159 | -1
160 | 87
161 | true
162 |
163 |
164 |
165 | 端口:
166 |
167 |
168 |
169 | -
170 |
171 |
172 |
173 | 微软雅黑
174 | -1
175 | 87
176 | true
177 |
178 |
179 |
180 | 打开串口
181 |
182 |
183 |
184 | -
185 |
186 |
187 | Qt::Vertical
188 |
189 |
190 | QSizePolicy::Fixed
191 |
192 |
193 |
194 | 20
195 | 10
196 |
197 |
198 |
199 |
200 | -
201 |
202 |
203 |
204 | 微软雅黑
205 | -1
206 | 87
207 | true
208 |
209 |
210 |
211 | 波特率:
212 |
213 |
214 |
215 | -
216 |
217 |
218 | QComboBox::AdjustToContentsOnFirstShow
219 |
220 |
221 | true
222 |
223 |
-
224 |
225 | 4800
226 |
227 |
228 | -
229 |
230 | 9600
231 |
232 |
233 | -
234 |
235 | 115200
236 |
237 |
238 |
239 |
240 | -
241 |
242 |
243 | -
244 |
245 |
246 | Qt::Vertical
247 |
248 |
249 | QSizePolicy::Fixed
250 |
251 |
252 |
253 | 20
254 | 10
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 | -
265 |
266 |
267 | QFrame#frame{
268 | color:rgb(60, 60, 60);
269 | background:rgb(30,30,30);
270 | border-top:1px solid darkGray;
271 | border-bottom:1px solid darkGray;
272 | border-right:1px solid darkGray;
273 | border-left:1px solid darkGray;
274 | border-top-right-radius:5px;
275 | border-bottom-right-radius:5px;
276 | border-top-left-radius:5px;
277 | border-bottom-left-radius:5px;
278 | }
279 |
280 | QLineEdit{
281 | font-size:12px;
282 | font-weight:700;
283 | font-family: "微软雅黑";
284 | }
285 |
286 | QPushButton{
287 | color:white;
288 | background:rgb(50,50,50); ;
289 | border-radius:3px;
290 | font-size:15px;
291 | font-weight:700;
292 | font-family: "微软雅黑";
293 | }
294 | QPushButton:hover{
295 | color:rgb(42,105,192);
296 | font-size:15px;
297 | font-weight:700;
298 | }
299 |
300 |
301 | QFrame::StyledPanel
302 |
303 |
304 | QFrame::Raised
305 |
306 |
307 |
-
308 |
309 |
-
310 |
311 |
312 |
313 | 微软雅黑
314 | -1
315 | 87
316 | true
317 |
318 |
319 |
320 | 发送数据
321 |
322 |
323 |
324 | -
325 |
326 |
327 | Qt::Vertical
328 |
329 |
330 | QSizePolicy::Fixed
331 |
332 |
333 |
334 | 20
335 | 10
336 |
337 |
338 |
339 |
340 | -
341 |
342 |
343 |
344 | 微软雅黑
345 | -1
346 | 87
347 | true
348 |
349 |
350 |
351 | I:
352 |
353 |
354 |
355 | -
356 |
357 |
358 |
359 | 微软雅黑
360 | -1
361 | 87
362 | true
363 |
364 |
365 |
366 | D:
367 |
368 |
369 |
370 | -
371 |
372 |
373 | Qt::Vertical
374 |
375 |
376 | QSizePolicy::Fixed
377 |
378 |
379 |
380 | 20
381 | 10
382 |
383 |
384 |
385 |
386 | -
387 |
388 |
389 |
390 | 微软雅黑
391 | -1
392 | 87
393 | true
394 |
395 |
396 |
397 | P:
398 |
399 |
400 |
401 | -
402 |
403 |
404 | Qt::Vertical
405 |
406 |
407 | QSizePolicy::Fixed
408 |
409 |
410 |
411 | 20
412 | 10
413 |
414 |
415 |
416 |
417 | -
418 |
419 |
420 |
421 | 微软雅黑
422 | -1
423 | 87
424 | true
425 |
426 |
427 |
428 | 操作:
429 |
430 |
431 |
432 | -
433 |
434 |
435 | 目标值:
436 |
437 |
438 |
439 | -
440 |
441 |
442 | Qt::Vertical
443 |
444 |
445 | QSizePolicy::Fixed
446 |
447 |
448 |
449 | 20
450 | 10
451 |
452 |
453 |
454 |
455 | -
456 |
457 |
458 | 清空数据
459 |
460 |
461 |
462 | -
463 |
464 |
465 | -
466 |
467 |
468 | -
469 |
470 |
471 | -
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 | -
480 |
481 |
482 | QPushButton{
483 | color:white;
484 | background:rgb(50,50,50); ;
485 | border-radius:3px;
486 | font-size:15px;
487 | font-weight:700;
488 | font-family: "微软雅黑";
489 | }
490 | QPushButton:hover{
491 | color:rgb(42,105,192);
492 | font-size:15px;
493 | font-weight:700;
494 | }
495 |
496 |
497 | QFrame::StyledPanel
498 |
499 |
500 | QFrame::Raised
501 |
502 |
503 |
-
504 |
505 |
506 | Qt::Vertical
507 |
508 |
509 | 1
510 |
511 |
512 |
513 | 打开示波器
514 |
515 |
516 |
517 |
518 | 垂直缩放
519 |
520 |
521 |
522 | 16
523 | 16
524 |
525 |
526 |
527 | false
528 |
529 |
530 | false
531 |
532 |
533 | false
534 |
535 |
536 |
537 |
538 | 发送数据
539 |
540 |
541 |
542 |
543 | 清空接收区
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 | -
555 |
556 |
557 | QLabel{
558 | border:none;
559 | color:white;
560 | font-size:26px;
561 | font-weight:700;
562 | font-family: "楷体";
563 | }
564 | QWidget#customPlot{
565 | color:#232C51;
566 | background:rgb(47,48,48);
567 | border-top:1px solid darkGray;
568 | border-bottom:1px solid darkGray;
569 | border-right:1px solid darkGray;
570 | border-left:1px solid darkGray;
571 | border-top-right-radius:10px;
572 | border-bottom-right-radius:10px;
573 | border-top-left-radius:10px;
574 | border-bottom-left-radius:10px;
575 | }
576 | QTextEdit{
577 | color: white;
578 | font-family: "JetBrains Mono";
579 | background:rgb(75,75,75);
580 | border-top:1px solid darkGray;
581 | border-bottom:1px solid darkGray;
582 | border-right:1px solid darkGray;
583 | border-left:1px solid darkGray;
584 | border-top-right-radius:10px;
585 | border-bottom-right-radius:10px;
586 | border-top-left-radius:10px;
587 | border-bottom-left-radius:10px;
588 | }
589 | QTextBrowser{
590 | color: white;
591 | font-size: 12px;
592 | font-family: "JetBrains Mono";
593 | background:rgb(75,75,75);
594 | border-top:1px solid darkGray;
595 | border-bottom:1px solid darkGray;
596 | border-right:1px solid darkGray;
597 | border-left:1px solid darkGray;
598 | border-top-right-radius:10px;
599 | border-bottom-right-radius:10px;
600 | border-top-left-radius:10px;
601 | border-bottom-left-radius:10px;
602 | }
603 |
604 |
605 |
-
606 |
607 |
608 | -
609 |
610 |
611 | -
612 |
613 |
614 |
615 | 楷体
616 | -1
617 | 87
618 | true
619 |
620 |
621 |
622 | 2021功率国赛工具—串口示波器
623 |
624 |
625 | Qt::AlignCenter
626 |
627 |
628 |
629 | -
630 |
631 |
632 | -
633 |
634 |
635 | QLabel{
636 | border:none;
637 | color:white;
638 | font-size:15px;
639 | font-weight:700;
640 | font-family: "微软雅黑";
641 | }
642 |
643 |
644 | 发送区
645 |
646 |
647 |
648 | -
649 |
650 |
651 | QLabel{
652 | border:none;
653 | color:white;
654 | font-size:15px;
655 | font-weight:700;
656 | font-family: "微软雅黑";
657 | }
658 |
659 |
660 | 接收区
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 | :/Images/Icons/gtk-help.png:/Images/Icons/gtk-help.png
674 |
675 |
676 | 使用说明
677 |
678 |
679 | Ctrl+H
680 |
681 |
682 |
683 |
684 |
685 | QCustomPlot
686 | QWidget
687 |
688 | 1
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
--------------------------------------------------------------------------------
/myresource.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | Icons/gtk-help.png
4 | Icons/Alien 2.png
5 |
6 |
7 |
--------------------------------------------------------------------------------