В предыдущей главе Qt отрисовка сигнала в реальном времени (с использованием QCustomPlot)_control shop blog-CSDN blog представил элемент управления отрисовкой сигнала в реальном времени на основе QCustomPlot и загрузил исходный код на ресурс CSDN, но от участников может потребоваться загрузите его, который ограничен Многие люди, которым нужен исходный код, загружают его. В этой главе я опубликую исходный код написанного мной элемента управления рисованием сигнала в реальном времени.
Ниже приведены исходные коды трех файлов класса WidgetPlot2D для управления рисованием сигналов в реальном времени, а именно widgetplot2d.cpp, widgetplot2d.h и widgetplot2d.ui.
файл widgetplot2d.cpp:
#include "widgetplot2d.h"
#include "ui_widgetplot2d.h"
#include <QDebug>
WidgetPlot2D::WidgetPlot2D(QWidget *parent) :
QWidget(parent),
ui(new Ui::WidgetPlot2D),
time(QTime::currentTime())
{
ui->setupUi(this);
// QCP绘图初始化
initQCP();
// 初始化控件
initWidget();
// 上下分裂器
ui->splitter->setStretchFactor(0, 20);
ui->splitter->setStretchFactor(1, 1);
// 左右分裂器
ui->splitter1->setStretchFactor(0, 10);
ui->splitter1->setStretchFactor(1, 3);
// 滚动条设置
ui->horizontalScrollBar->setRange(0, 0);
// 拖动水平滚动条,图幅跟随变化
connect(ui->horizontalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(horzScrollBarChanged(int)));
// 默认坐标范围
ui->customPlot->yAxis->setRange(-20, 20);
ui->customPlot->replot();
}
WidgetPlot2D::~WidgetPlot2D()
{
delete ui;
}
/* 初始化曲线名称 */
void WidgetPlot2D::initGraphName(QStringList name)
{
//----------------------------------------------------------------------------------------//
// 设置表头
ui->treeWidget->setHeaderLabels(QStringList() << "名称" << "值" << "颜色");
ui->treeWidget->header()->setVisible(true);
// 表头文字中间对齐
QTreeWidgetItem* header = ui->treeWidget->headerItem();
header->setTextAlignment(0, Qt::AlignLeft);
header->setTextAlignment(1, Qt::AlignLeft);
header->setTextAlignment(2, Qt::AlignLeft);
// 设置列宽
ui->treeWidget->setColumnWidth(0, 100);
ui->treeWidget->setColumnWidth(1, 90);
ui->treeWidget->setColumnWidth(2, 30);
// 表头顺序是否可以拖动改变
ui->treeWidget->header()->setCascadingSectionResizes(true);
// 被选部分是否高亮显示
ui->treeWidget->header()->setHighlightSections(false);
// 最后一个区域是否占满表格余下的所有部分
ui->treeWidget->header()->setStretchLastSection(true);
// 列表的列数
ui->treeWidget->setColumnCount(3);
//----------------------------------------------------------------------------------------//
for (int i = 0; i < name.length(); i++) {
// 添加曲线列表项
QTreeWidgetItem* item = new QTreeWidgetItem;
ui->treeWidget->addTopLevelItem(item);
//----------------------------------------------------------------------------------------//
// 向曲线列表项第一列添加曲线是否可见复选框
QCheckBox* isShowCheckBox = new QCheckBox(name.at(i));
isShowCheckBox->setChecked(true);
connect(isShowCheckBox, SIGNAL(stateChanged(int)), this, SLOT(changeGraphVisible()));
ui->treeWidget->setItemWidget(item, 0, isShowCheckBox);
isShowCheckBoxVector.append(isShowCheckBox);
//----------------------------------------------------------------------------------------//
// 向曲线列表项第二列添加曲线数值标签
QLabel* valueLabel = new QLabel("0");
QFont font("Courier");
valueLabel->setFont(font);
//valueLabel->setAlignment(Qt::AlignHCenter);
ui->treeWidget->setItemWidget(item, 1, valueLabel);
valueLabelVector.append(valueLabel);
//----------------------------------------------------------------------------------------//
// 向曲线列表项第三列添加曲线颜色按钮,点击该按钮弹出颜色选择框,选择曲线颜色
QPushButton* GraphColorPushButton = new QPushButton("");
// 随机分配初始按钮背景色
static int r = 0, g = 0, b = 0;
r += 150; g += 50; b += 100;
if (r > 255) r -= 255;
if (g > 255) g -= 255;
if (b > 255) b -= 255;
QPalette pal;
pal.setColor(QPalette::Button, QColor(r, g, b));
GraphColorPushButton->setPalette(pal);
GraphColorPushButton->setAutoFillBackground(true); // 该句不能缺少,否则背景颜色无法改变
GraphColorPushButton->setFlat(true);
// 固定颜色按钮大小
GraphColorPushButton->setMinimumHeight(18); // 固定高度
GraphColorPushButton->setMaximumHeight(18);
GraphColorPushButton->setMinimumWidth(30); // 固定宽度
GraphColorPushButton->setMaximumWidth(30);
connect(GraphColorPushButton, SIGNAL(clicked()), this, SLOT(changeGraphColor()));
ui->treeWidget->setItemWidget(item, 2, GraphColorPushButton);
GraphColorPushButtonVector.append(GraphColorPushButton);
//----------------------------------------------------------------------------------------//
// 添加曲线
ui->customPlot->addGraph();
ui->customPlot->graph(ui->customPlot->graphCount()-1)->setPen(QPen(QColor(r, g, b)));
ui->customPlot->graph(ui->customPlot->graphCount()-1)->setVisible(true);
// 将曲线名称与曲线序号一一对应,之后添加数据就可以一一对应
nameToGraphMap[name.at(i)] = i;
// 初始化数据容器的值
for (int t = 0; t < name.length(); t++) {
valueVector.append(0);
}
}
}
/* 添加数据 */
void WidgetPlot2D::addData(QString name, double value)
{
// 如果点击了“暂停”按钮,则不绘制图形
if (ui->pausePBtn->text() == "开始") return;
// 系统当前时间 = 系统运行初始时间 + 系统运行时间
static double start = time.hour()*60*60 + time.minute()*60 + time.second() + time.msec()/1000.0;
double key = start + time.elapsed()/1000.0;
// 子网格显示
ui->customPlot->xAxis->grid()->setSubGridVisible(ui->subGridCheck->isChecked());
ui->customPlot->yAxis->grid()->setSubGridVisible(ui->subGridCheck->isChecked());
// 自适应量程
if (ui->autoRangeCheck->isChecked()) {
ui->customPlot->rescaleAxes();
}
// 设置时间轴
int timeAxis = ui->timeAxisSpin->value();
ui->customPlot->xAxis->setRange(key, timeAxis, Qt::AlignRight);
// x轴和y轴全程显示
if (ui->fullShowCheck->isChecked()) {
ui->customPlot->rescaleAxes();
}
// 刷新绘图水平滚动条
ui->horizontalScrollBar->setRange(int(start), int(key)); // 刷新滚动条的范围
ui->horizontalScrollBar->setPageStep(1); // 设置翻页步长为 1s 的宽度
ui->horizontalScrollBar->setValue(int(key)); // 调整滑块位置到最右边
// 更新曲线绘图
ui->customPlot->graph(nameToGraphMap[name])->addData(key, value);
//ui->customPlot->replot();
// 使用rpQueuedReplot参数可以加快绘图速度,避免不必要的重复绘制
ui->customPlot->replot(QCustomPlot::rpQueuedReplot);
// 存储曲线的当前值
valueVector[nameToGraphMap[name]] = value;
//----------------------------------------------------------------------------------------//
// 计算每秒的帧率
static double lastFpsKey = key;
static int frameCount = 0;
frameCount++;
// 每2秒显示一次帧率
if (key-lastFpsKey > 0.5) {
uint64_t sum = 0;
for (int i = 0; i < ui->customPlot->plottableCount(); i++) {
sum += uint64_t(ui->customPlot->graph(i)->data()->size());
}
ui->statusLabel->setText(QString("%1 FPS, Total Data points: %2").arg(frameCount/(key-lastFpsKey), 0, 'f', 0).arg(sum));
lastFpsKey = key;
frameCount = 0;
// 更新数据标签
for (int t = 0; t < ui->customPlot->plottableCount(); t++) {
valueLabelVector[t]->setText(QString::number(valueVector[t]));
}
}
//----------------------------------------------------------------------------------------//
}
/* 曲线是否显示 */
void WidgetPlot2D::changeGraphVisible()
{
for (int i = 0; i < isShowCheckBoxVector.length(); i++) {
ui->customPlot->graph(i)->setVisible(isShowCheckBoxVector[i]->isChecked());
}
}
/* 改变曲线颜色 */
void WidgetPlot2D::changeGraphColor()
{
/* 在槽(SLOT)中sender()函数会返回一个指向 QObject 的指针来指向信号的发送者。
* 然后通过 C++ RTTI(Run-Time Type Identification)机制提供的dynamic_cast运算符,
* 在执行的时候检查sender()返回的对象是否是QPushButton类,如果是则将sender()返回的QObject指针转换为QPushButton指针,
* 然后if中的语句就会执行。如果sender()返回的对象不是QPushButton类型的指针,则dynamic_cast就会返回0,if中的语句就不会执行了。
* */
if (QPushButton* btn = dynamic_cast<QPushButton*>(sender())) {
QColor color = QColorDialog::getColor(Qt::white, this);
// 用户取消颜色对话框
if (color.isValid() == false)
return;
// 设置按钮背景色
QPalette pal;// = btn->palette();
pal.setColor(QPalette::Button, color);
btn->setPalette(pal);
btn->setAutoFillBackground(true); // 该句不能缺少,否则背景颜色无法改变
btn->setFlat(true); // 该句不能缺少,否则背景颜色无法改变
}
// 改变对应的曲线颜色
for (int i = 0; i < GraphColorPushButtonVector.length(); i++) {
// 获取按钮的颜色
QPalette pal = GraphColorPushButtonVector[i]->palette();
QColor color = pal.color(QPalette::Button);
// 曲线颜色对应按钮颜色
ui->customPlot->graph(i)->setPen(QPen(color));
}
ui->customPlot->replot();
}
/* QCP绘图初始化 */
void WidgetPlot2D::initQCP()
{
// 刻度显示
ui->customPlot->xAxis->setTicks(true);
ui->customPlot->yAxis->setTicks(true);
// 刻度值显示
ui->customPlot->xAxis->setTickLabels(true);
ui->customPlot->yAxis->setTickLabels(true);
// 网格显示
ui->customPlot->xAxis->grid()->setVisible(true);
ui->customPlot->yAxis->grid()->setVisible(true);
// 子网格显示
ui->customPlot->xAxis->grid()->setSubGridVisible(false);
ui->customPlot->yAxis->grid()->setSubGridVisible(false);
// 右和上坐标轴、刻度值显示
ui->customPlot->xAxis2->setVisible(true);
ui->customPlot->yAxis2->setVisible(true);
ui->customPlot->yAxis2->setTicks(true);
ui->customPlot->yAxis2->setTickLabels(true);
// make top right axes clones of bottom left axes. Looks prettier:
// ui->customPlot->axisRect()->setupFullAxesBox();
// make left and bottom axes always transfer their ranges to right and top axes:
connect(ui->customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), ui->customPlot->xAxis2, SLOT(setRange(QCPRange)));
connect(ui->customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), ui->customPlot->yAxis2, SLOT(setRange(QCPRange)));
// 暗色主题
//setPlotTheme(Qt::white, Qt::black);
// 亮色主题
setTheme(Qt::black, Qt::white);
// 可放大缩小和移动
ui->customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
// x轴以时间形式显示
QSharedPointer<QCPAxisTickerTime> timeTicker(new QCPAxisTickerTime);
timeTicker->setTimeFormat("%h:%m:%s");
ui->customPlot->xAxis->setTicker(timeTicker);
ui->customPlot->axisRect()->setupFullAxesBox();
ui->customPlot->replot();
}
/* 设置绘图主题 */
void WidgetPlot2D::setTheme(QColor axis, QColor background)
{
// 坐标颜色按钮
QPalette pal = ui->axisColorPBtn->palette();
pal.setColor(QPalette::Button, axis);
ui->axisColorPBtn->setPalette(pal);
ui->axisColorPBtn->setAutoFillBackground(true); // 该句不能缺少,否则背景颜色无法改变
ui->axisColorPBtn->setFlat(true); // 该句不能缺少,否则背景颜色无法改变
// 背景颜色按钮
pal = ui->backgroundColorPBtn->palette();
pal.setColor(QPalette::Button, background);
ui->backgroundColorPBtn->setPalette(pal);
ui->backgroundColorPBtn->setAutoFillBackground(true); // 该句不能缺少,否则背景颜色无法改变
ui->backgroundColorPBtn->setFlat(true); // 该句不能缺少,否则背景颜色无法改变
//----------------------------------------------------------------------------------------//
// 坐标标注颜色
ui->customPlot->xAxis->setLabelColor(axis);
ui->customPlot->yAxis->setLabelColor(axis);
// 坐标刻度值颜色
ui->customPlot->xAxis->setTickLabelColor(axis);
ui->customPlot->yAxis->setTickLabelColor(axis);
// 坐标基线颜色和宽度
ui->customPlot->xAxis->setBasePen(QPen(axis, 1));
ui->customPlot->yAxis->setBasePen(QPen(axis, 1));
// 坐标主刻度颜色和宽度
ui->customPlot->xAxis->setTickPen(QPen(axis, 1));
ui->customPlot->yAxis->setTickPen(QPen(axis, 1));
// 坐标子刻度颜色和宽度
ui->customPlot->xAxis->setSubTickPen(QPen(axis, 1));
ui->customPlot->yAxis->setSubTickPen(QPen(axis, 1));
// 坐标标注颜色
ui->customPlot->xAxis2->setLabelColor(axis);
ui->customPlot->yAxis2->setLabelColor(axis);
// 坐标刻度值颜色
ui->customPlot->xAxis2->setTickLabelColor(axis);
ui->customPlot->yAxis2->setTickLabelColor(axis);
// 坐标基线颜色和宽度
ui->customPlot->xAxis2->setBasePen(QPen(axis, 1));
ui->customPlot->yAxis2->setBasePen(QPen(axis, 1));
// 坐标主刻度颜色和宽度
ui->customPlot->xAxis2->setTickPen(QPen(axis, 1));
ui->customPlot->yAxis2->setTickPen(QPen(axis, 1));
// 坐标子刻度颜色和宽度
ui->customPlot->xAxis2->setSubTickPen(QPen(axis, 1));
ui->customPlot->yAxis2->setSubTickPen(QPen(axis, 1));
// 整个画布背景色
ui->customPlot->setBackground(background);
// 绘图区域背景色
ui->customPlot->axisRect()->setBackground(background);
// 刷新绘图
ui->customPlot->replot();
}
/* 初始化控件 */
void WidgetPlot2D::initWidget()
{
// 时间轴默认时间宽度
ui->timeAxisSpin->setValue(20);
// 主题
QStringList theme;
theme << "亮色" << "暗色" << "自定义";
ui->themeCombo->addItems(theme);
connect(ui->themeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(changePlotTheme()));
//----------------------------------------------------------------------------------------//
// 坐标颜色按钮
QPalette pal = ui->axisColorPBtn->palette();
pal.setColor(QPalette::Button, Qt::black);
ui->axisColorPBtn->setPalette(pal);
ui->axisColorPBtn->setAutoFillBackground(true); // 该句不能缺少,否则背景颜色无法改变
ui->axisColorPBtn->setFlat(true); // 该句不能缺少,否则背景颜色无法改变
connect(ui->axisColorPBtn, SIGNAL(clicked()), this, SLOT(changePlotTheme()));
// 背景颜色按钮
pal = ui->backgroundColorPBtn->palette();
pal.setColor(QPalette::Button, Qt::white);
ui->backgroundColorPBtn->setPalette(pal);
ui->backgroundColorPBtn->setAutoFillBackground(true); // 该句不能缺少,否则背景颜色无法改变
ui->backgroundColorPBtn->setFlat(true); // 该句不能缺少,否则背景颜色无法改变
connect(ui->backgroundColorPBtn, SIGNAL(clicked()), this, SLOT(changePlotTheme()));
// 操作按钮
connect(ui->clearPBtn, SIGNAL(clicked()), this, SLOT(plotOperation()));
connect(ui->fullShowPBtn, SIGNAL(clicked()), this, SLOT(plotOperation()));
connect(ui->savePBtn, SIGNAL(clicked()), this, SLOT(plotOperation()));
connect(ui->pausePBtn, SIGNAL(clicked()), this, SLOT(plotOperation()));
//----------------------------------------------------------------------------------------//
}
/* 改变画图主题 */
void WidgetPlot2D::changePlotTheme()
{
// 主题选择
if (QComboBox* combo = dynamic_cast<QComboBox*>(sender()))
{
if (combo->currentText() == "亮色") {
setTheme(Qt::black, Qt::white); // 亮色主题
}
else if (combo->currentText() == "暗色") {
setTheme(Qt::white, Qt::black); // 暗色主题
}
else if (combo->currentText() == "自定义") {
// 绘图坐标颜色
QPalette axisPal = ui->axisColorPBtn->palette();
QColor axisColor = axisPal.color(QPalette::Button);
// 绘图背景颜色
QPalette backgroundPal = ui->backgroundColorPBtn->palette();
QColor backgroundColor = backgroundPal.color(QPalette::Button);
setTheme(axisColor, backgroundColor);
}
}
// 用户自定义主题
if (QPushButton* btn = dynamic_cast<QPushButton*>(sender())) {
QColor color = QColorDialog::getColor(Qt::white, this);
// 用户取消颜色对话框
if (color.isValid() == false)
return;
// 设置按钮背景色
QPalette pal = btn->palette();
pal.setColor(QPalette::Button, color);
btn->setPalette(pal);
btn->setAutoFillBackground(true); // 该句不能缺少,否则背景颜色无法改变
btn->setFlat(true); // 该句不能缺少,否则背景颜色无法改变
// 绘图坐标颜色
QPalette axisPal = ui->axisColorPBtn->palette();
QColor axisColor = axisPal.color(QPalette::Button);
// 绘图背景颜色
QPalette backgroundPal = ui->backgroundColorPBtn->palette();
QColor backgroundColor = backgroundPal.color(QPalette::Button);
// 改变主题颜色
setTheme(axisColor, backgroundColor);
ui->themeCombo->setCurrentText("自定义");
}
}
/* 绘图操作 */
void WidgetPlot2D::plotOperation()
{
if (QPushButton* btn = dynamic_cast<QPushButton*>(sender())) {
if (btn->text() == "清除") {
for (int i = 0; i < ui->customPlot->graphCount(); i++) {
// 先获得每条曲线的数据指针,然后删除数据
ui->customPlot->graph(i)->data()->clear();
ui->customPlot->replot();
time = QTime::currentTime();
}
}
if (btn->text() == "整图") {
ui->customPlot->rescaleAxes();
ui->customPlot->replot();
}
if (btn->text() == "保存") {
savePlotPng();
}
if (btn->text() == "暂停") {
btn->setText("开始");
QIcon icon(":/image/player.png");
btn->setIcon(icon);
} else if (btn->text() == "开始") {
btn->setText("暂停");
QIcon icon(":/image/pause.png");
btn->setIcon(icon);
}
}
}
/* 判断路径是否存在,不存在则新建,只能创建一级子目录,必须保证上级目录存在 */
bool WidgetPlot2D::isDirExist(QString fullPath)
{
QDir dir(fullPath);
if(dir.exists()) {
return true;
} else {
// 创建一级子目录,必须保证上级目录存在
bool ok = dir.mkdir(fullPath);
return ok;
}
}
/* 保存绘图成图片 */
void WidgetPlot2D::savePlotPng()
{
// 获取程序运行路径
QString savePath = QCoreApplication::applicationDirPath() + "/output";
// 判断文件路径
if (isDirExist(savePath)) {
} else {
qDebug() << "保存文件目录未找到!";
QMessageBox::warning(this,
"warning",
"保存文件目录未找到!",
QMessageBox::Yes,
QMessageBox::Yes);
}
QString fileName = QFileDialog::getSaveFileName(this,
"保存波形数据", // 对话框的标题
savePath, // 保存的默认路径为程序运行路径
"Save Picture (*.png *jpg)"); // 打开文件的类型,;隔开
// 如果用户点击了“取消”按钮
if (fileName.isNull())
return;
// 保存图片
ui->customPlot->savePng(fileName, 1280, 800, 1.0, -1, 255);
}
/* 水平滚动条移动 */
void WidgetPlot2D::horzScrollBarChanged(int value)
{
// 若全程显示,则不移动绘图坐标
if (ui->fullShowCheck->isChecked())
return;
int timeAxis = ui->timeAxisSpin->value();
ui->customPlot->xAxis->setRange(value, timeAxis, Qt::AlignRight);
ui->customPlot->replot();
}
файл widgetplot2d.h:
#ifndef WIDGETPLOT2D_H
#define WIDGETPLOT2D_H
#include <QWidget>
#include <QCheckBox>
#include <QLabel>
#include <QPushButton>
#include "qcustomplot.h"
namespace Ui {
class WidgetPlot2D;
}
class WidgetPlot2D : public QWidget
{
Q_OBJECT
public:
explicit WidgetPlot2D(QWidget *parent = 0);
~WidgetPlot2D();
void initGraphName(QStringList name);
private:
Ui::WidgetPlot2D *ui;
QVector<QCheckBox*> isShowCheckBoxVector; // 是否显示勾选框
QVector<QLabel*> valueLabelVector; // label数值显示
QVector<QPushButton*> GraphColorPushButtonVector; // 曲线颜色选择按钮
QMap<QString, int> nameToGraphMap; // 曲线名称对应曲线序号
QVector<double> valueVector; // 存储曲线的当前值
QTime time;
void initQCP();
void initWidget();
void setTheme(QColor axis, QColor background);
bool isDirExist(QString fullPath);
void savePlotPng();
private slots:
void changeGraphVisible();
void changeGraphColor();
void plotOperation();
void horzScrollBarChanged(int value);
void changePlotTheme();
public slots:
void addData(QString name, double data);
};
#endif // WIDGETPLOT2D_H
файл widgetplot2d.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>WidgetPlot2D</class>
<widget class="QWidget" name="WidgetPlot2D">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>904</width>
<height>531</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="styleSheet">
<string notr="true">/******************** QGroupBox ***********************/
QGroupBox#plotUiGroup, #plotShowGroup, #plotOperGroup, #plotSetupGroup
{
min-width: 150px;
max-width: 150px;
min-height: 100px;
max-height: 100px;
border: 1px solid darkGreen;
border-radius: 8px;
background: rgba(250, 240, 230, 0.7); /*背景半透明 */
margin: 5px 0px 0px 0px;
}
QGroupBox#plotGroup
{
border: 1px solid darkGreen;
border-radius: 3px;
margin: 5px 0px 0px 0px;
}
QGroupBox::title
{
subcontrol-origin: margin;
subcontrol-position: top;
}
/****************** QPushButton *******************/
QPushButton#clearPBtn, #fullShowPBtn, #savePBtn, #openPBtn, #pausePBtn
{
border: 1px solid black;
background-color: lightGray;
width: 25px;
height: 20px;
border-radius: 5px; /* 边框圆角半径 */
}
QPushButton#clearPBtn:hover, #fullShowPBtn:hover, #savePBtn:hover, #openPBtn:hover, #pausePBtn:hover
{
border: 1px solid darkCyan;
border-radius: 5px; /* 边框圆角半径 */
}
QPushButton#clearPBtn:pressed, #fullShowPBtn:pressed, #savePBtn:pressed, #openPBtn:pressed, #pausePBtn:pressed
{
color: white;
border: 1px solid darkCyan;
background-color: darkCyan; /* 背景 */
border-radius: 5px; /* 边框圆角半径 */
}
/***********************QScrollBar****************************/
</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSplitter" name="splitter1">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QGroupBox" name="plotGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string/>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>1</number>
</property>
<property name="leftMargin">
<number>1</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>1</number>
</property>
<item>
<widget class="QCustomPlot" name="customPlot" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QScrollBar" name="horizontalScrollBar">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="layoutWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QGroupBox" name="plotUiGroup">
<property name="title">
<string>颜色</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QComboBox" name="themeCombo"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>坐标颜色</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>主题</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>背景颜色</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="backgroundColorPBtn">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="axisColorPBtn">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="plotShowGroup">
<property name="title">
<string>显示</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="autoRangeCheck">
<property name="text">
<string>自适应量程</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="subGridCheck">
<property name="text">
<string>显示子网格</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>时间轴:</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QSpinBox" name="timeAxisSpin">
<property name="suffix">
<string> s</string>
</property>
<property name="prefix">
<string/>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>999999999</number>
</property>
<property name="value">
<number>10</number>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QCheckBox" name="fullShowCheck">
<property name="text">
<string>全程</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="plotOperGroup">
<property name="minimumSize">
<size>
<width>152</width>
<height>107</height>
</size>
</property>
<property name="title">
<string>操作</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="2">
<widget class="QPushButton" name="fullShowPBtn">
<property name="text">
<string>整图</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="clearPBtn">
<property name="text">
<string>清除</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="savePBtn">
<property name="text">
<string>保存</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="pausePBtn">
<property name="text">
<string>暂停</string>
</property>
<property name="icon">
<iconset resource="image.qrc">
<normaloff>:/image/pause.png</normaloff>:/image/pause.png</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="statusLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>绘图状态</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QTreeWidget" name="treeWidget">
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QCustomPlot</class>
<extends>QWidget</extends>
<header>qcustomplot.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="image.qrc"/>
</resources>
<connections/>
</ui>