注:串口分析过程中偶尔会出现问题
.pro
#------------------------------------------------- # # Project created by QtCreator 2021-03-09T09:33:42 # #------------------------------------------------- QT = core gui serialport printsupport greaterThan(QT_MAJOR_VERSION, 4): QT = widgets TARGET = untitled TEMPLATE = app # The following define makes your compiler emit warnings if you use # any feature of Qt which has been marked as deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES = QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES = QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 CONFIG = c 11 SOURCES = \ graph.cpp \ main.cpp \ mainwindow.cpp \ qcustomplot.cpp \ resolver.cpp \ serial.cpp HEADERS = \ fftw3.h \ graph.h \ mainwindow.h \ qcustomplot.h \ resolver.h \ serial.h FORMS = \ mainwindow.ui # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS = target LIBS = -L$$PWD/./ -llibfftw3-3 INCLUDEPATH = $$PWD/. DEPENDPATH = $$PWD/.
fftw3.h是fftw项目中需要包含的自带头文件
graph.h
#ifndef GRAPH_H #define GRAPH_H #include <QMainWindow> #include "qcustomplot.h" #endif // GRAPH_H
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include "serial.h" #include "graph.h" #include "resolver.h" namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); QVector<double> x,y0,y1; signals: void start_resolver(); public slots: void slot_graph(); private slots: void on_pushButton_clicked(); void on_pushButton_2_clicked(); void readyRead_slot(QByteArray data); void on_actionserial_triggered(bool checked); void on_dockWidget_visibilityChanged(bool visible); void on_pushButton_3_clicked(); private: Ui::MainWindow *ui; serial *myserial; resolver *m_resolver; QThread *m_thread; void graph_init(); void customplot1_add_graph(void); void customplot2_add_graph(void); }; #endif // MAINWINDOW_H
qcustomplot.h是Qt外部仓库用于显示波形qcustomplot的头文件
resolver.h
#ifndef RESOLVER_H #define RESOLVER_H #include <QObject> #include <QThread> #include "fftw3.h" #define N 256 #define UART_BUF_SIZE 200 class resolver : public QObject { Q_OBJECT public: explicit resolver(QObject *parent = nullptr); ~resolver(); signals: void start_graph(); public slots: void do_resolver(); private: void do_fft(); void do_resolver2(char *char_data,uint8_t len); }; struct channel_data { uint16_t average_value; uint16_t current_value; uint16_t power; uint16_t Shredded; }; #endif // RESOLVER_H
serial.h
#ifndef SERIAL_H #define SERIAL_H #include <QObject> #include <QSerialPort> #include <QSerialPortInfo> #include "qserialport.h" #include "QString" class serial:public QObject { Q_OBJECT public: serial(QObject *o=0); ~serial(); bool openPort(QString portName,qint32 baudRate,QSerialPort::DataBits dataBits, QSerialPort::Parity parity,QSerialPort::StopBits stopBits, QSerialPort::FlowControl flowControl); bool isOpen(); void closePort(); QStringList getAvailablePortNameList(); void write(QString str); void write(const char *data, qint64 len); QString ByteArrayToHexString(QByteArray data); signals: void readyRead(QByteArray data); private: QSerialPort *m_port; void readyRead_slot(); }; #endif // SERIAL_H
graph.cpp
#include "graph.h" #include "mainwindow.h" #include "ui_mainwindow.h" #include <QVector> #include <stdio.h> extern fftw_complex *in, *out; /*-------------------------------------------*/ ///画动态曲线时,使用输入数据addData,多次调用定时器,然后调用ui->widget->replot(); 动态曲线可以通过另一种设置坐标来解决坐标问题: //setRange ( double position, double size, Qt::AlignmentFlag alignment )
//参数分别为:原点,偏移量,对其方式,有兴趣的读者可自行尝试,欢迎垂询
/*-------------------------------------------*/
void MainWindow::graph_init()
{
x.resize(N);
for(int i=0;i<N;i++)
{
x[i]=i;
}
y0.resize(N);
y1.resize(N);
//设定背景为黑色
//ui->widget->setBackground(QBrush(Qt::black));
//设置X轴文字标注
ui->widget->xAxis->setLabel("time");
ui->widget_2->xAxis->setLabel("time");
//设置Y轴文字标注
ui->widget->yAxis->setLabel("short HbO2");
ui->widget_2->yAxis->setLabel("short HbO2");
//设置X轴坐标范围
ui->widget->xAxis->setRange(0,N);
ui->widget_2->xAxis->setRange(0,N/2);
//设置Y轴坐标范围
ui->widget->yAxis->setRange(0,3000);
ui->widget_2->yAxis->setRange(0,3000);
//在坐标轴右侧和上方画线,和X/Y轴一起形成一个矩形
//ui->widget->axisRect()->setupFullAxesBox();
//设置基本坐标轴(左侧Y轴和下方X轴)可拖动、可缩放、曲线可选、legend可选、设置伸缩比例,使所有图例可见
ui->widget->setInteractions(QCP::iRangeDrag|QCP::iRangeZoom| QCP::iSelectAxes |
QCP::iSelectLegend | QCP::iSelectPlottables);
ui->widget_2->setInteractions(QCP::iRangeDrag|QCP::iRangeZoom| QCP::iSelectAxes |
QCP::iSelectLegend | QCP::iSelectPlottables);
//设定右上角图形标注可见
//ui->widget->legend->setVisible(true);
//设定右上角图形标注的字体
//ui->widget->legend->setFont(QFont("Helvetica", 9));
/*曲线0*/
customplot1_add_graph();
customplot2_add_graph();
//draw test
// for(int i=0;i<100;i++)
// {
// y0[0] = 2*i+1;
// ui->widget->graph(0)->addData(x,y0);
// x[0]=i;
// }
}
void MainWindow::customplot1_add_graph()
{
//添加图形
ui->widget->addGraph();
//设置画笔
QPen pen0(Qt::red, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
ui->widget->graph(0)->setPen(pen0);
//ui->widget->graph(0)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ScatterShape::ssPlus,5));
//设置画刷,曲线和X轴围成面积的颜色
//ui->widget->graph(0)->setBrush(QBrush(QColor(255,255,0)));
//设置右上角图形标注名称
ui->widget->graph(0)->setName("曲线");
//传入数据,setData的两个参数类型为double
//ui->widget->graph(0)->setLineStyle(QCPGraph::lsLine);//lsNone/lsLine/lsStepLeft/lsStepRight/lsStepCenter/lsImpulse
//ui->widget->graph(0)->addData(x,y);
// y0[0]=0;
// ui->widget->graph(0)->setData(x,y0);
//根据图像最高点最低点自动缩放坐标轴
//Y轴
//ui->widget->graph(0)->rescaleValueAxis(true);
//X轴
//ui->widget->graph(0)->rescaleKeyAxis(true);
//X、Y轴
//ui->widget->graph(0)->rescaleAxes(true);
}
void MainWindow::customplot2_add_graph()
{
//添加图形
ui->widget_2->addGraph();
//设置画笔
QPen pen0(Qt::blue, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
ui->widget_2->graph(0)->setPen(pen0);
//ui->widget->graph(0)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ScatterShape::ssPlus,5));
//设置画刷,曲线和X轴围成面积的颜色
//ui->widget->graph(0)->setBrush(QBrush(QColor(255,255,0)));
//设置右上角图形标注名称
ui->widget_2->graph(0)->setName("曲线");
}
void MainWindow::slot_graph()
{
for(int i=0;i<N;i++)
{
y0[i]=in[i][0];
y1[i]=out[i][0];
}
ui->widget->graph(0)->setData(x,y0);
ui->widget->replot();
ui->widget_2->graph(0)->setData(x,y1);
ui->widget_2->replot();
}
main.cpp不做解释
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QDebug"
char uart_buf[UART_BUF_SIZE];
uint16_t uart_buf_point=0;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
myserial(new serial)
{
ui->setupUi(this);
QStringList baudRate;
baudRate<<"115200"<<"9600";
ui->comboBox_2->addItems(baudRate);
m_thread=new QThread;
connect(m_thread,&QThread::started,this,
[this]
{
qDebug()<<"thread started";
},Qt::UniqueConnection);
connect(m_thread,&QThread::finished,this,
[this]
{
qDebug()<<"thread finished";
},Qt::UniqueConnection);
connect(m_thread,&QThread::destroyed,this,
[this]
{
qDebug()<<"thread destroyed";
},Qt::UniqueConnection);
m_resolver=new resolver();
m_resolver->moveToThread(m_thread);
connect(m_thread, &QThread::finished, this, &QObject::deleteLater,Qt::UniqueConnection);
connect(m_thread, &QThread::finished, m_thread, &QObject::deleteLater,Qt::UniqueConnection);
connect(this,&MainWindow::start_resolver,m_resolver,&resolver::do_resolver,Qt::UniqueConnection);
connect(m_resolver,&resolver::start_graph,this,&MainWindow::slot_graph,Qt::UniqueConnection);
m_thread->start();
emit start_resolver();
//初始化graph
graph_init();
}
MainWindow::~MainWindow()
{
delete ui;
delete myserial;
delete m_resolver;
m_thread->quit();
m_thread->wait();
delete m_thread;
}
/*搜索串口*/
void MainWindow::on_pushButton_clicked()
{
QStringList SerialName=myserial->getAvailablePortNameList();
ui->comboBox->clear();
ui->comboBox->addItems(SerialName);
}
/*打开/关闭串口*/
void MainWindow::on_pushButton_2_clicked()
{
if(ui->pushButton_2->text()=="打开串口")
{
ui->pushButton_2->setText("关闭串口");
bool ok;
myserial->openPort(ui->comboBox->currentText(),
ui->comboBox_2->currentText().toInt(&ok,10),
QSerialPort::Data8,
QSerialPort::NoParity,
QSerialPort::OneStop,
QSerialPort::NoFlowControl);
//connect(myserial,&serial::readyRead,this,&MainWindow::readyRead_slot);
connect(myserial, SIGNAL(readyRead(QByteArray)), this, SLOT(readyRead_slot(QByteArray)),Qt::UniqueConnection);
}
else if(ui->pushButton_2->text()=="关闭串口")
{
ui->pushButton_2->setText("打开串口");
myserial->closePort();
disconnect(myserial, SIGNAL(readyRead(QByteArray)), this, SLOT(readyRead_slot(QByteArray)));
}
}
/*接收到串口数据处理槽函数*/
void MainWindow::readyRead_slot(QByteArray data)
{
ui->textBrowser->moveCursor(QTextCursor::End);
ui->textBrowser->insertPlainText(data);
char *char_data=data.data();
if(data.length()+uart_buf_point<=UART_BUF_SIZE)
{
memcpy(&(uart_buf[uart_buf_point]),char_data,data.length());
uart_buf_point+=data.length();
if(uart_buf_point==UART_BUF_SIZE)
{
uart_buf_point=0;
}
}
else
{
if(data.length()>UART_BUF_SIZE)
{
//qDebug()<<"data.length()>UART_BUF_SIZE";
return;
}
//qDebug()<<"接续存放";
uint16_t part1_size=UART_BUF_SIZE-uart_buf_point;
uint16_t part2_size=data.length()-part1_size;
memcpy(&(uart_buf[uart_buf_point]),char_data,part1_size);
uart_buf_point=0;
memcpy(&(uart_buf[uart_buf_point]),char_data+part1_size,part2_size);
uart_buf_point+=part2_size;
}
}
//serial窗口的action被点击
void MainWindow::on_actionserial_triggered(bool checked)
{
if(checked==1){
ui->dockWidget->show();
}
else {
ui->dockWidget->hide();
}
}
//dockWidget显示被改变
void MainWindow::on_dockWidget_visibilityChanged(bool visible)
{
if(!visible)
{
ui->menu->actions().at(0)->setChecked(0);
}
if(visible)
{
ui->menu->actions().at(0)->setChecked(1);
}
}
void MainWindow::on_pushButton_3_clicked()
{
QByteArray tmp("12,34,56,78,21,43,65,87",23);
tmp.append('\n');
readyRead_slot(tmp);
}
qcustomplot.cpp是Qt中用来显示波形的外部库qcustomplot的源码文件
resolver.cpp
#include "resolver.h"
#include "QDebug"
#include "QString"
#include "math.h"
uint16_t counter=0;
fftw_complex *in, *out;//声明复数类型的输入数据in1_c和FFT变换的结果out1_c
uint16_t read_uart_buf_point=0;
extern uint16_t uart_buf_point;
extern char uart_buf[];
resolver::resolver(QObject *parent) : QObject(parent)
{
in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)* N);//申请动态内存
out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)* N);
memset(in,0,sizeof(fftw_complex)* N);
memset(out,0,sizeof(fftw_complex)* N);
}
resolver::~resolver()
{
fftw_free(in);
fftw_free(out);//释放内存
}
void resolver::do_resolver()
{
uint16_t start=0;
char *buf;
uint16_t size=0;
while(1)
{
if(read_uart_buf_point!=uart_buf_point)
{
if(uart_buf[read_uart_buf_point]=='\n')
{
if(read_uart_buf_point>start)
{
size=read_uart_buf_point+1-start;
buf=(char *)malloc(size);
memcpy((char *)buf,(char *)&(uart_buf[start]),size);
}
else
{
//qDebug()<<"接续读";
uint16_t p1_size=UART_BUF_SIZE-start;
uint16_t p2_size=read_uart_buf_point+1;
size=p1_size+p2_size;
buf=(char *)malloc(p1_size+p2_size);
memcpy((char *)buf,(char *)&(uart_buf[start]),p1_size);
memcpy((char *)buf+p1_size,(char *)&(uart_buf[0]),p2_size);
}
do_resolver2(buf,size);
free(buf);
start=read_uart_buf_point+1;
if(start<UART_BUF_SIZE)
{
}
else
{
start=0;
}
read_uart_buf_point=start;
}
else
{
if(read_uart_buf_point<UART_BUF_SIZE)
{
read_uart_buf_point++;
}
else
{
//qDebug()<<"read_uart_buf_point=0";
read_uart_buf_point=0;
}
}
}
else
{
//qDebug()<<"缓冲区为空";
}
}
}
#define FOR_GO(data,cnt) ((data[cnt]=='0')||(data[cnt]=='1')||(data[cnt]=='2')||(data[cnt]=='3')||(data[cnt]=='4')||(data[cnt]=='5')||(data[cnt]=='6')||(data[cnt]=='7')||(data[cnt]=='8')||(data[cnt]=='9'))
#define FOR_CK(data,cnt) ((data[cnt]!=',')&&(data[cnt]!='\r')&&(data[cnt]!='\n'))
void resolver::do_resolver2(char *char_data,uint8_t len)
{
struct channel_data ch1_data,ch2_data;
int start,next,which=0;
char *buf=NULL;
int tmp_value=0;
QString str;
for(int i=0;i<len;i++)
{
str.append(char_data[i]);
}
qDebug()<<str;
for(start=0;FOR_GO(char_data,start);start=next+1)
{
for(next=start;FOR_GO(char_data,next);++next)
{
if (next >= len)
{
qDebug()<<"too long";
goto err;
}
}
if(FOR_CK(char_data,next))
{
qDebug()<<"check1";
goto err;
}
if(next-start)
{
which++;
}
else
{
qDebug()<<"check2";
goto err;
}
buf=(char *)malloc(next-start+1);
memcpy((char *)buf,(char *)&(char_data[start]),next-start);
buf[next-start]='\0';
tmp_value=atoi(buf);
//qDebug()<<tmp_value;
if(buf!=NULL)
{
free(buf);
}
switch(which)
{
case 1:
ch1_data.average_value=tmp_value;
break;
case 2:
ch1_data.current_value=tmp_value;
break;
case 3:
ch1_data.power=tmp_value;
break;
case 4:
ch1_data.Shredded=tmp_value;
break;
case 5:
ch2_data.average_value=tmp_value;
break;
case 6:
ch2_data.current_value=tmp_value;
break;
case 7:
ch2_data.power=tmp_value;
break;
case 8:
ch2_data.Shredded=tmp_value;
if((char_data[next]=='\r')||(char_data[next]=='\n'))
{
goto ok;
}
else
{
qDebug()<<"8";
goto err;
}
break;
}
}
qDebug()<<"?";
err:
qDebug()<<"err";
if(counter==0)
{
}
if(counter>=N)
{
counter=0;
}
else
{
in[counter][0]=in[counter-1][0];
//qDebug()<<in[counter][0];
counter++;
}
goto fft;
ok:
if(counter==0)
{
in[counter][0]=ch1_data.current_value;
//qDebug()<<in[counter][0];
counter++;
}
if(counter>=N)
{
counter=0;
in[counter][0]=ch1_data.current_value;
//qDebug()<<in[counter][0];
counter++;
}
else
{
in[counter][0]=ch1_data.current_value;
//qDebug()<<in[counter][0];
counter++;
}
goto fft;
fft:
if(counter==N)
{
do_fft();
}
}
void resolver::do_fft()
{
fftw_plan p;//声明变换策略
// for(int i=0;i<N/4;i++)
// {
// in[4*i][0]=1;
// in[4*i+1][0]=0;
// in[4*i+2][0]=-1;
// in[4*i+3][0]=0;
// }
p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE);//返回变换策略
fftw_execute(p);//执行变换
fftw_destroy_plan(p);//销毁策略
out[0][0]=out[0][0]/N;
for(int i=1;i<N;i++)
{
out[i][0]=sqrt(out[i][0]*out[i][0]+out[i][1]*out[i][1])/(N/2);
}
// for (int i = 0; i < N; i++)
// {
// qDebug()<<i<<"= "<<out[i][0]<<out[i][1];
// }
emit start_graph();
}
serial.cpp
#include "serial.h"
#include "QDebug"
serial::serial(QObject *o)
{
m_port = new QSerialPort();
connect(m_port,&QSerialPort::readyRead,this,&serial::readyRead_slot,Qt::UniqueConnection);
}
serial::~serial()
{
delete m_port;
disconnect(m_port,&QSerialPort::readyRead,this,&serial::readyRead_slot);
}
/**
* @functionName openPort
* @brief 打开串口 根据名字 波特率 数据位 校验位 停止位 流控制
* @return 打开成功还是失败
*/
bool serial::openPort(QString portName, qint32 baudRate,
QSerialPort::DataBits dataBits, QSerialPort::Parity parity,
QSerialPort::StopBits stopBits, QSerialPort::FlowControl flowControl)
{
m_port->setPortName(portName);
m_port->setBaudRate(baudRate);
m_port->setDataBits(dataBits);
m_port->setParity(parity);
m_port->setStopBits(stopBits);
m_port->setFlowControl(flowControl);
if(m_port->open(QIODevice::ReadWrite))
{
return true;
}
else
return false;
}
/**
* @projectName testMyClass
* @brief 是否打开串口
*/
bool serial::isOpen()
{
return m_port->isOpen();
}
/**
* @projectName testMyClass
* @brief 关闭串口
*/
void serial::closePort()
{
m_port->clear();
m_port->close();
}
/**
* @projectName testMyClass
* @brief 获取可用的串口名字
*/
QStringList serial::getAvailablePortNameList()
{
QStringList portName;
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
portName<<info.portName();
}
return portName;
}
/**
* @projectName testMyClass
* @brief 串口写数据
*/
void serial::write(QString str)
{
m_port->write(str.toUtf8().data());
}
void serial::write(const char *data, qint64 len)
{
m_port->write(data,len);
}
/**
* @projectName testMyClass
* @brief QByteArray 转换为 QString
*/
QString serial::ByteArrayToHexString(QByteArray data)
{
QString ret(data.toHex().toUpper());
int len = ret.length()/2;
for(int i=1;i<len;i++)
{
ret.insert(2*i+i-1," ");
}
return ret;
}
/**
* @projectName testMyClass
* @brief 串口读取到数据的信号
*/
void serial::readyRead_slot()
{
QByteArray data = m_port->readAll();
emit readyRead(data);
}
ui_mainwindow.h
/********************************************************************************
** Form generated from reading UI file 'mainwindow.ui'
**
** Created by: Qt User Interface Compiler version 5.12.3
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QDockWidget>
#include <QtWidgets/QFrame>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenu>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QTabWidget>
#include <QtWidgets/QTextBrowser>
#include <QtWidgets/QToolBar>
#include <QtWidgets/QWidget>
#include <qcustomplot.h>
QT_BEGIN_NAMESPACE
class Ui_MainWindow
{
public:
QAction *actionserial;
QWidget *centralWidget;
QGridLayout *gridLayout;
QFrame *line;
QCustomPlot *widget;
QCustomPlot *widget_2;
QMenuBar *menuBar;
QMenu *menu;
QToolBar *mainToolBar;
QDockWidget *dockWidget;
QWidget *dockWidgetContents_6;
QGridLayout *gridLayout_2;
QTabWidget *tabWidget;
QWidget *tab_3;
QGridLayout *gridLayout_4;
QTextBrowser *textBrowser;
QLineEdit *lineEdit;
QComboBox *comboBox;
QComboBox *comboBox_2;
QPushButton *pushButton;
QPushButton *pushButton_2;
QPushButton *pushButton_3;
QWidget *tab_4;
QGridLayout *gridLayout_5;
QTextBrowser *textBrowser_2;
QStatusBar *statusBar;
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(676, 502);
MainWindow->setStyleSheet(QString::fromUtf8("#MainWindow\n"
"{\n"
"background-color: rgb(60, 60, 60);\n"
"}"));
actionserial = new QAction(MainWindow);
actionserial->setObjectName(QString::fromUtf8("actionserial"));
actionserial->setCheckable(true);
actionserial->setChecked(false);
centralWidget = new QWidget(MainWindow);
centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
centralWidget->setStyleSheet(QString::fromUtf8("#centralWidget\n"
"{\n"
"background-color: rgb(255, 255, 255);\n"
"}"));
gridLayout = new QGridLayout(centralWidget);
gridLayout->setSpacing(6);
gridLayout->setContentsMargins(11, 11, 11, 11);
gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
line = new QFrame(centralWidget);
line->setObjectName(QString::fromUtf8("line"));
line->setStyleSheet(QString::fromUtf8("background-color: rgb(0, 0, 0);"));
line->setFrameShape(QFrame::VLine);
line->setFrameShadow(QFrame::Sunken);
gridLayout->addWidget(line, 1, 2, 3, 1);
widget = new QCustomPlot(centralWidget);
widget->setObjectName(QString::fromUtf8("widget"));
QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
sizePolicy.setHeightForWidth(widget->sizePolicy().hasHeightForWidth());
widget->setSizePolicy(sizePolicy);
widget->setCursor(QCursor(Qt::CrossCursor));
widget->setAutoFillBackground(false);
widget->setStyleSheet(QString::fromUtf8(""));
gridLayout->addWidget(widget, 1, 0, 2, 1);
widget_2 = new QCustomPlot(centralWidget);
widget_2->setObjectName(QString::fromUtf8("widget_2"));
sizePolicy.setHeightForWidth(widget_2->sizePolicy().hasHeightForWidth());
widget_2->setSizePolicy(sizePolicy);
widget_2->setCursor(QCursor(Qt::CrossCursor));
widget_2->setAutoFillBackground(false);
widget_2->setStyleSheet(QString::fromUtf8(""));
gridLayout->addWidget(widget_2, 3, 0, 2, 1);
MainWindow->setCentralWidget(centralWidget);
menuBar = new QMenuBar(MainWindow);
menuBar->setObjectName(QString::fromUtf8("menuBar"));
menuBar->setGeometry(QRect(0, 0, 676, 23));
menuBar->setCursor(QCursor(Qt::PointingHandCursor));
menuBar->setStyleSheet(QString::fromUtf8("#menuBar\n"
"{\n"
"background-color: rgb(200, 200, 200);\n"
"}"));
menu = new QMenu(menuBar);
menu->setObjectName(QString::fromUtf8("menu"));
MainWindow->setMenuBar(menuBar);
mainToolBar = new QToolBar(MainWindow);
mainToolBar->setObjectName(QString::fromUtf8("mainToolBar"));
mainToolBar->setMinimumSize(QSize(0, 30));
mainToolBar->setCursor(QCursor(Qt::PointingHandCursor));
mainToolBar->setAutoFillBackground(false);
mainToolBar->setStyleSheet(QString::fromUtf8("color: rgb(255, 255, 255);\n"
"mainToolBar{background-color: rgb(60, 60, 60);};"));
MainWindow->addToolBar(Qt::TopToolBarArea, mainToolBar);
dockWidget = new QDockWidget(MainWindow);
dockWidget->setObjectName(QString::fromUtf8("dockWidget"));
dockWidget->setEnabled(true);
dockWidget->setFocusPolicy(Qt::NoFocus);
dockWidget->setContextMenuPolicy(Qt::DefaultContextMenu);
dockWidget->setAcceptDrops(false);
dockWidget->setLayoutDirection(Qt::LeftToRight);
dockWidget->setAutoFillBackground(false);
dockWidget->setStyleSheet(QString::fromUtf8("#dockWidget\n"
"{\n"
"background-color: rgb(60, 60, 60);\n"
" color: rgb(255, 255, 255);\n"
"}"));
dockWidget->setFeatures(QDockWidget::DockWidgetClosable);
dockWidget->setAllowedAreas(Qt::BottomDockWidgetArea);
dockWidgetContents_6 = new QWidget();
dockWidgetContents_6->setObjectName(QString::fromUtf8("dockWidgetContents_6"));
dockWidgetContents_6->setStyleSheet(QString::fromUtf8("#dockWidgetContents_6\n"
"{\n"
"background-color: rgb(60, 60, 60);\n"
"}"));
gridLayout_2 = new QGridLayout(dockWidgetContents_6);
gridLayout_2->setSpacing(6);
gridLayout_2->setContentsMargins(11, 11, 11, 11);
gridLayout_2->setObjectName(QString::fromUtf8("gridLayout_2"));
gridLayout_2->setContentsMargins(-1, -1, -1, 0);
tabWidget = new QTabWidget(dockWidgetContents_6);
tabWidget->setObjectName(QString::fromUtf8("tabWidget"));
tabWidget->setAutoFillBackground(false);
tabWidget->setStyleSheet(QString::fromUtf8(""));
tabWidget->setTabPosition(QTabWidget::South);
tabWidget->setTabShape(QTabWidget::Rounded);
tabWidget->setElideMode(Qt::ElideNone);
tabWidget->setTabBarAutoHide(false);
tab_3 = new QWidget();
tab_3->setObjectName(QString::fromUtf8("tab_3"));
tab_3->setStyleSheet(QString::fromUtf8(""));
gridLayout_4 = new QGridLayout(tab_3);
gridLayout_4->setSpacing(6);
gridLayout_4->setContentsMargins(11, 11, 11, 11);
gridLayout_4->setObjectName(QString::fromUtf8("gridLayout_4"));
textBrowser = new QTextBrowser(tab_3);
textBrowser->setObjectName(QString::fromUtf8("textBrowser"));
textBrowser->setEnabled(true);
sizePolicy.setHeightForWidth(textBrowser->sizePolicy().hasHeightForWidth());
textBrowser->setSizePolicy(sizePolicy);
textBrowser->setMinimumSize(QSize(0, 20));
textBrowser->viewport()->setProperty("cursor", QVariant(QCursor(Qt::IBeamCursor)));
gridLayout_4->addWidget(textBrowser, 0, 0, 1, 5);
lineEdit = new QLineEdit(tab_3);
lineEdit->setObjectName(QString::fromUtf8("lineEdit"));
gridLayout_4->addWidget(lineEdit, 1, 0, 1, 5);
comboBox = new QComboBox(tab_3);
comboBox->setObjectName(QString::fromUtf8("comboBox"));
sizePolicy.setHeightForWidth(comboBox->sizePolicy().hasHeightForWidth());
comboBox->setSizePolicy(sizePolicy);
gridLayout_4->addWidget(comboBox, 2, 0, 1, 1);
comboBox_2 = new QComboBox(tab_3);
comboBox_2->setObjectName(QString::fromUtf8("comboBox_2"));
sizePolicy.setHeightForWidth(comboBox_2->sizePolicy().hasHeightForWidth());
comboBox_2->setSizePolicy(sizePolicy);
gridLayout_4->addWidget(comboBox_2, 2, 1, 1, 1);
pushButton = new QPushButton(tab_3);
pushButton->setObjectName(QString::fromUtf8("pushButton"));
sizePolicy.setHeightForWidth(pushButton->sizePolicy().hasHeightForWidth());
pushButton->setSizePolicy(sizePolicy);
gridLayout_4->addWidget(pushButton, 2, 2, 1, 1);
pushButton_2 = new QPushButton(tab_3);
pushButton_2->setObjectName(QString::fromUtf8("pushButton_2"));
sizePolicy.setHeightForWidth(pushButton_2->sizePolicy().hasHeightForWidth());
pushButton_2->setSizePolicy(sizePolicy);
gridLayout_4->addWidget(pushButton_2, 2, 3, 1, 1);
pushButton_3 = new QPushButton(tab_3);
pushButton_3->setObjectName(QString::fromUtf8("pushButton_3"));
sizePolicy.setHeightForWidth(pushButton_3->sizePolicy().hasHeightForWidth());
pushButton_3->setSizePolicy(sizePolicy);
gridLayout_4->addWidget(pushButton_3, 2, 4, 1, 1);
tabWidget->addTab(tab_3, QString());
tab_4 = new QWidget();
tab_4->setObjectName(QString::fromUtf8("tab_4"));
gridLayout_5 = new QGridLayout(tab_4);
gridLayout_5->setSpacing(6);
gridLayout_5->setContentsMargins(11, 11, 11, 11);
gridLayout_5->setObjectName(QString::fromUtf8("gridLayout_5"));
textBrowser_2 = new QTextBrowser(tab_4);
textBrowser_2->setObjectName(QString::fromUtf8("textBrowser_2"));
gridLayout_5->addWidget(textBrowser_2, 0, 0, 1, 1);
tabWidget->addTab(tab_4, QString());
gridLayout_2->addWidget(tabWidget, 1, 0, 1, 1);
dockWidget->setWidget(dockWidgetContents_6);
MainWindow->addDockWidget(static_cast<Qt::DockWidgetArea>(8), dockWidget);
statusBar = new QStatusBar(MainWindow);
statusBar->setObjectName(QString::fromUtf8("statusBar"));
statusBar->setMinimumSize(QSize(0, 20));
statusBar->setStyleSheet(QString::fromUtf8("color: rgb(255, 255, 255);"));
MainWindow->setStatusBar(statusBar);
menuBar->addAction(menu->menuAction());
menu->addAction(actionserial);
mainToolBar->addAction(actionserial);
mainToolBar->addSeparator();
retranslateUi(MainWindow);
tabWidget->setCurrentIndex(0);
QMetaObject::connectSlotsByName(MainWindow);
} // setupUi
void retranslateUi(QMainWindow *MainWindow)
{
MainWindow->setWindowTitle(QApplication::translate("MainWindow", "\344\270\273\351\241\265", nullptr));
actionserial->setText(QApplication::translate("MainWindow", "serial", nullptr));
#ifndef QT_NO_STATUSTIP
actionserial->setStatusTip(QApplication::translate("MainWindow", "\344\270\262\345\217\243\347\252\227\345\217\243", nullptr));
#endif // QT_NO_STATUSTIP
menu->setTitle(QApplication::translate("MainWindow", "\347\252\227\345\217\243", nullptr));
#ifndef QT_NO_WHATSTHIS
dockWidget->setWhatsThis(QApplication::translate("MainWindow", "<html><head/><body><p><br/></p></body></html>", nullptr));
#endif // QT_NO_WHATSTHIS
#ifndef QT_NO_ACCESSIBILITY
dockWidget->setAccessibleName(QString());
#endif // QT_NO_ACCESSIBILITY
dockWidget->setWindowTitle(QApplication::translate("MainWindow", "serial", nullptr));
textBrowser->setHtml(QApplication::translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:'SimSun'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>", nullptr));
pushButton->setText(QApplication::translate("MainWindow", "\346\220\234\347\264\242\344\270\262\345\217\243", nullptr));
pushButton_2->setText(QApplication::translate("MainWindow", "\346\211\223\345\274\200\344\270\262\345\217\243", nullptr));
pushButton_3->setText(QApplication::translate("MainWindow", "\345\217\221\351\200\201", nullptr));
tabWidget->setTabText(tabWidget->indexOf(tab_3), QApplication::translate("MainWindow", "serial", nullptr));
tabWidget->setTabText(tabWidget->indexOf(tab_4), QApplication::translate("MainWindow", " \345\272\224\347\224\250\347\250\213\345\272\217\350\276\223\345\207\272", nullptr));
} // retranslateUi
};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MAINWINDOW_H
mainwindow.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>676</width>
<height>502</height>
</rect>
</property>
<property name="windowTitle">
<string>主页</string>
</property>
<property name="styleSheet">
<string notr="true">#MainWindow
{
background-color: rgb(60, 60, 60);
}</string>
</property>
<widget class="QWidget" name="centralWidget">
<property name="styleSheet">
<string notr="true">#centralWidget
{
background-color: rgb(255, 255, 255);
}</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="2" rowspan="3">
<widget class="Line" name="line">
<property name="styleSheet">
<string notr="true">background-color: rgb(0, 0, 0);</string>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="1" column="0" rowspan="2">
<widget class="QCustomPlot" name="widget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="cursor">
<cursorShape>CrossCursor</cursorShape>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
</widget>
</item>
<item row="3" column="0" rowspan="2">
<widget class="QCustomPlot" name="widget_2" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="cursor">
<cursorShape>CrossCursor</cursorShape>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>676</width>
<height>23</height>
</rect>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="styleSheet">
<string notr="true">#menuBar
{
background-color: rgb(200, 200, 200);
}</string>
</property>
<widget class="QMenu" name="menu">
<property name="title">
<string>窗口</string>
</property>
<addaction name="actionserial"/>
</widget>
<addaction name="menu"/>
</widget>
<widget class="QToolBar" name="mainToolBar">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true">color: rgb(255, 255, 255);
mainToolBar{background-color: rgb(60, 60, 60);};</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionserial"/>
<addaction name="separator"/>
</widget>
<widget class="QDockWidget" name="dockWidget">
<property name="enabled">
<bool>true</bool>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="contextMenuPolicy">
<enum>Qt::DefaultContextMenu</enum>
</property>
<property name="acceptDrops">
<bool>false</bool>
</property>
<property name="whatsThis">
<string><html><head/><body><p><br/></p></body></html></string>
</property>
<property name="accessibleName">
<string/>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true">#dockWidget
{
background-color: rgb(60, 60, 60);
color: rgb(255, 255, 255);
}</string>
</property>
<property name="features">
<set>QDockWidget::DockWidgetClosable</set>
</property>
<property name="allowedAreas">
<set>Qt::BottomDockWidgetArea</set>
</property>
<property name="windowTitle">
<string>serial</string>
</property>
<attribute name="dockWidgetArea">
<number>8</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_6">
<property name="styleSheet">
<string notr="true">#dockWidgetContents_6
{
background-color: rgb(60, 60, 60);
}</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="bottomMargin">
<number>0</number>
</property>
<item row="1" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="tabPosition">
<enum>QTabWidget::South</enum>
</property>
<property name="tabShape">
<enum>QTabWidget::Rounded</enum>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<property name="elideMode">
<enum>Qt::ElideNone</enum>
</property>
<property name="tabBarAutoHide">
<bool>false</bool>
</property>
<widget class="QWidget" name="tab_3">
<property name="styleSheet">
<string notr="true"/>
</property>
<attribute name="title">
<string>serial</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0" colspan="5">
<widget class="QTextBrowser" name="textBrowser">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="cursor" stdset="0">
<cursorShape>IBeamCursor</cursorShape>
</property>
<property name="html">
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'SimSun'; font-size:9pt; font-weight:400; font-style:normal;">
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="5">
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item row="2" column="0">
<widget class="QComboBox" name="comboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="comboBox_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="pushButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>搜索串口</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QPushButton" name="pushButton_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>打开串口</string>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QPushButton" name="pushButton_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>发送</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_4">
<attribute name="title">
<string> 应用程序输出</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<widget class="QTextBrowser" name="textBrowser_2"/>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QStatusBar" name="statusBar">
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">color: rgb(255, 255, 255);</string>
</property>
</widget>
<action name="actionserial">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="text">
<string>serial</string>
</property>
<property name="statusTip">
<string>串口窗口</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>QCustomPlot</class>
<extends>QWidget</extends>
<header location="global">qcustomplot.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
界面图片