增加效果

main
HwangKC 2025-03-05 13:37:23 +08:00
parent ea0722e7e7
commit 67df1624b7
20 changed files with 2342 additions and 19 deletions

View File

@ -1,4 +1,4 @@
QT += core gui QT += core gui serialport serialbus
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
@ -10,6 +10,8 @@ CONFIG += c++17
SOURCES += \ SOURCES += \
appinit.cpp \ appinit.cpp \
customwidget.cpp \
formserialportsettingdialog.cpp \
libmodbus/modbus-data.c \ libmodbus/modbus-data.c \
libmodbus/modbus-rtu.c \ libmodbus/modbus-rtu.c \
libmodbus/modbus-tcp.c \ libmodbus/modbus-tcp.c \
@ -19,6 +21,8 @@ SOURCES += \
HEADERS += \ HEADERS += \
appinit.h \ appinit.h \
customwidget.h \
formserialportsettingdialog.h \
libmodbus/config.h \ libmodbus/config.h \
libmodbus/modbus-private.h \ libmodbus/modbus-private.h \
libmodbus/modbus-rtu-private.h \ libmodbus/modbus-rtu-private.h \
@ -31,6 +35,7 @@ HEADERS += \
slave_define.h slave_define.h
FORMS += \ FORMS += \
formserialportsettingdialog.ui \
mainwindow.ui mainwindow.ui
LIBS += -lws2_32 LIBS += -lws2_32

View File

@ -0,0 +1,100 @@
#include "customwidget.h"
#include <QVBoxLayout>
#include <QLabel>
#include <QTextEdit>
#include <QTableWidget>
#include <QHeaderView>
#include <QGraphicsDropShadowEffect>
CustomWidget::CustomWidget(QWidget *parent)
: QWidget{parent}
{
QWidget *centralWidget = new QWidget();
QGridLayout *mainLayout = new QGridLayout(this);
mainLayout->addWidget(centralWidget);
//实例阴影shadow
QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(this);
//设置阴影距离
shadow->setOffset(0, 0);
//设置阴影颜色
shadow->setColor(QColor(44,44,44));
//设置阴影圆角
shadow->setBlurRadius(16);
//给嵌套QDialog设置阴影
centralWidget->setGraphicsEffect(shadow);
QVBoxLayout *mainLayout1 = new QVBoxLayout(centralWidget);
mainLayout1->setSpacing(5); // 控件间间隔
// 上1/3QLabel
QWidget *topWidget = new QWidget();
mainLayout1->addWidget(topWidget, 1); // 拉伸因子为1
setupTopSection(topWidget);
// 中1/3两个垂直排列的QTextEdit
QWidget *midWidget = new QWidget();
mainLayout1->addWidget(midWidget, 1);
setupMidSection(midWidget);
// 下1/3表格
QWidget *bottomWidget = new QWidget();
mainLayout1->addWidget(bottomWidget, 1);
setupBottomSection(bottomWidget);
}
void CustomWidget::setupTopSection(QWidget *parent)
{
//实例阴影shadow
QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(this);
//设置阴影距离
shadow->setOffset(0, 0);
//设置阴影颜色
shadow->setColor(QColor(244,44,44));
//设置阴影圆角
shadow->setBlurRadius(16);
QLabel *label = new QLabel("顶部标签", parent);
label->setAlignment(Qt::AlignCenter);
label->setGraphicsEffect(shadow);
QVBoxLayout *layout = new QVBoxLayout(parent);
layout->addWidget(label);
}
void CustomWidget::setupMidSection(QWidget *parent)
{
//实例阴影shadow
QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(this);
//设置阴影距离
shadow->setOffset(0, 0);
//设置阴影颜色
shadow->setColor(QColor(244,44,44));
//设置阴影圆角
shadow->setBlurRadius(16);
QVBoxLayout *layout = new QVBoxLayout(parent);
QTextEdit *textEdit1 = new QTextEdit();
QTextEdit *textEdit2 = new QTextEdit();
layout->addWidget(textEdit1, 1); // 各占中间区域的一半高度
layout->addWidget(textEdit2, 1);
}
void CustomWidget::setupBottomSection(QWidget *parent)
{
//实例阴影shadow
QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(this);
//设置阴影距离
shadow->setOffset(0, 0);
//设置阴影颜色
shadow->setColor(QColor(244,44,44));
//设置阴影圆角
shadow->setBlurRadius(16);
QTableWidget *table = new QTableWidget(5, 2, parent); // 5行2列
table->setHorizontalHeaderLabels({"列1", "列2"});
table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); // 列宽自适应
table->setGraphicsEffect(shadow);
QVBoxLayout *layout = new QVBoxLayout(parent);
layout->addWidget(table);
}

View File

@ -0,0 +1,21 @@
#ifndef CUSTOMWIDGET_H
#define CUSTOMWIDGET_H
#include <QWidget>
class CustomWidget : public QWidget
{
Q_OBJECT
public:
explicit CustomWidget(QWidget *parent = nullptr);
private:
void setupTopSection(QWidget *parent);
void setupMidSection(QWidget *parent);
void setupBottomSection(QWidget *parent);
signals:
};
#endif // CUSTOMWIDGET_H

View File

@ -0,0 +1,160 @@
#include "formserialportsettingdialog.h"
#include "ui_formserialportsettingdialog.h"
#include <QListView>
#include <QStandardItemModel>
#include <QPushButton>
#include <QMessageBox>
#include <QFile>
#include <QTextStream>
#include <QByteArray>
#include <QDebug>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QGraphicsDropShadowEffect>
#include <QSettings>
FormSerialPortSettingDialog::FormSerialPortSettingDialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::FormSerialPortSettingDialog)
{
ui->setupUi(this);
InitializeUi();
}
FormSerialPortSettingDialog::~FormSerialPortSettingDialog()
{
delete ui;
}
void FormSerialPortSettingDialog::InitializeUi()
{
this->setStyleSheet("background-color: white;");
this->setProperty("canMove",true);
//设置窗体透明
this->setAttribute(Qt::WA_TranslucentBackground, true);
//设置无边框
this->setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
//实例阴影shadow
QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(this);
//设置阴影距离
shadow->setOffset(0, 0);
//设置阴影颜色
shadow->setColor(QColor(44,44,44));
//设置阴影圆角
shadow->setBlurRadius(16);
//给嵌套QDialog设置阴影
ui->w_bg->setGraphicsEffect(shadow);
//给垂直布局器设置边距(此步很重要, 设置宽度为阴影的宽度)
//ui->lay_bg->setMargin(12);
QApplication::setOverrideCursor(Qt::WaitCursor);
ui->delay_timeout->setText("1000");
ui->slave_id->setText("1");
//设置奇偶校验
ui->cb_parity->setView(new QListView(this));
ui->cb_parity->addItem("NoParity", QVariant::fromValue(QSerialPort::NoParity));
ui->cb_parity->addItem("Even", QVariant::fromValue(QSerialPort::EvenParity));
ui->cb_parity->addItem("Odd", QVariant::fromValue(QSerialPort::OddParity));
ui->cb_parity->setCurrentIndex(0);
//设置数据位
ui->cb_data->setView(new QListView(this));
ui->cb_data->addItem("5", QVariant::fromValue(QSerialPort::Data5));
ui->cb_data->addItem("6", QVariant::fromValue(QSerialPort::Data6));
ui->cb_data->addItem("7", QVariant::fromValue(QSerialPort::Data7));
ui->cb_data->addItem("8", QVariant::fromValue(QSerialPort::Data8));
ui->cb_data->setCurrentIndex(3);
//设置数据位
ui->cb_stop->setView(new QListView(this));
ui->cb_stop->addItem("1", QVariant::fromValue(QSerialPort::OneStop));
ui->cb_stop->addItem("2", QVariant::fromValue(QSerialPort::TwoStop));
ui->cb_stop->addItem("3", QVariant::fromValue(QSerialPort::OneAndHalfStop));
ui->cb_stop->setCurrentIndex(0);
//设置串口模式
//ui->cb_baund->setView(new QListView(this));
//QStandardItemModel* model_baund = new QStandardItemModel(this);
ui->cb_baund->addItem("4800", QVariant::fromValue(QSerialPort::Baud4800));
ui->cb_baund->addItem("9600", QVariant::fromValue(QSerialPort::Baud9600));
ui->cb_baund->addItem("19200", QVariant::fromValue(QSerialPort::Baud19200));
ui->cb_baund->addItem("38400", QVariant::fromValue(QSerialPort::Baud38400));
ui->cb_baund->addItem("57600", QVariant::fromValue(QSerialPort::Baud57600));
ui->cb_baund->addItem("115200", QVariant::fromValue(QSerialPort::Baud115200));
ui->cb_baund->setCurrentIndex(1);
//设置串口类型
ui->cb_type->setView(new QListView(this));
ui->cb_type->addItem("Modbus RTU");
//设置串口号
ui->cb_serialport->setView(new QListView(this));
QStringList comport = get_avail_sp_();
foreach (const QString& str, comport)
{
QStringList parts = str.split("-", Qt::SkipEmptyParts);
ui->cb_serialport->addItem(str,parts[0].trimmed());
}
ui->buttonBox->clear();
QPushButton *okButton = ui->buttonBox->addButton(QDialogButtonBox::Ok);
QPushButton *cancelButton = ui->buttonBox->addButton(QDialogButtonBox::Cancel);
okButton->setFixedSize(100, 30);
cancelButton->setFixedSize(100, 30);
connect(okButton, &QPushButton::clicked, this, &FormSerialPortSettingDialog::onOkClicked);
connect(cancelButton, &QPushButton::clicked, this, &FormSerialPortSettingDialog::onCancelClicked);
// 恢复默认光标
QApplication::restoreOverrideCursor();
}
QStringList FormSerialPortSettingDialog::get_avail_sp_() noexcept
{
QStringList list_avail_sp;
foreach (const QSerialPortInfo &port, QSerialPortInfo::availablePorts())
{
list_avail_sp.append(port.portName() + " - " + port.description());
}
list_avail_sp.sort();
return list_avail_sp;
}
void FormSerialPortSettingDialog::onOkClicked()
{
//写到INI文件
QString appDir = QCoreApplication::applicationDirPath();
QString iniFilePath = appDir + QString::fromStdString("/emsshower.ini");
QSettings* pSettings = new QSettings(iniFilePath, QSettings::IniFormat,this);
//写选中的串口
int baund = ui->cb_baund->currentData().toInt();
QString com = ui->cb_serialport->currentData().toString();
int data = ui->cb_data->currentData().toInt();
int parity = ui->cb_parity->currentData().toInt();
int stop = ui->cb_stop->currentData().toInt();
int slave_id = ui->slave_id->text().toInt();
pSettings->setValue("modbus/baund",baund);
pSettings->setValue("modbus/com",com);
pSettings->setValue("modbus/data",data);
pSettings->setValue("modbus/parity",parity);
pSettings->setValue("modbus/stop",stop);
pSettings->setValue("slaves/slave_id",slave_id);
accept();
}
void FormSerialPortSettingDialog::onCancelClicked()
{
QDialog::reject();
}

View File

@ -0,0 +1,32 @@
#ifndef FORMSERIALPORTSETTINGDIALOG_H
#define FORMSERIALPORTSETTINGDIALOG_H
#include <QDialog>
#include <QStringList>
namespace Ui
{
class FormSerialPortSettingDialog;
}
class FormSerialPortSettingDialog : public QDialog
{
Q_OBJECT
public:
explicit FormSerialPortSettingDialog(QWidget *parent = nullptr);
~FormSerialPortSettingDialog();
private:
Ui::FormSerialPortSettingDialog *ui;
protected:
void InitializeUi();
QStringList get_avail_sp_() noexcept;
private slots:
void onOkClicked();
void onCancelClicked();
};
#endif // FORMSERIALPORTSETTINGDIALOG_H

View File

@ -0,0 +1,265 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FormSerialPortSettingDialog</class>
<widget class="QDialog" name="FormSerialPortSettingDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>665</width>
<height>320</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QWidget" name="w_bg" native="true">
<property name="geometry">
<rect>
<x>7</x>
<y>6</y>
<width>651</width>
<height>310</height>
</rect>
</property>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>30</x>
<y>20</y>
<width>69</width>
<height>19</height>
</rect>
</property>
<property name="text">
<string>串口类型</string>
</property>
<property name="buddy">
<cstring>cb_type</cstring>
</property>
</widget>
<widget class="QLabel" name="label_9">
<property name="geometry">
<rect>
<x>341</x>
<y>102</y>
<width>69</width>
<height>19</height>
</rect>
</property>
<property name="text">
<string>停止位</string>
</property>
<property name="buddy">
<cstring>cb_stop</cstring>
</property>
</widget>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>280</x>
<y>243</y>
<width>341</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QLabel" name="label_11">
<property name="geometry">
<rect>
<x>30</x>
<y>183</y>
<width>91</width>
<height>19</height>
</rect>
</property>
<property name="text">
<string>响应超时</string>
</property>
<property name="buddy">
<cstring>delay_timeout</cstring>
</property>
</widget>
<widget class="QLabel" name="label_7">
<property name="geometry">
<rect>
<x>30</x>
<y>140</y>
<width>69</width>
<height>19</height>
</rect>
</property>
<property name="text">
<string>数据位</string>
</property>
<property name="buddy">
<cstring>cb_data</cstring>
</property>
</widget>
<widget class="QLabel" name="label_8">
<property name="geometry">
<rect>
<x>340</x>
<y>140</y>
<width>69</width>
<height>19</height>
</rect>
</property>
<property name="text">
<string>校验位</string>
</property>
<property name="buddy">
<cstring>cb_parity</cstring>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>30</x>
<y>60</y>
<width>69</width>
<height>19</height>
</rect>
</property>
<property name="text">
<string>串口号</string>
</property>
</widget>
<widget class="QComboBox" name="cb_stop">
<property name="geometry">
<rect>
<x>421</x>
<y>102</y>
<width>201</width>
<height>25</height>
</rect>
</property>
</widget>
<widget class="QComboBox" name="cb_data">
<property name="geometry">
<rect>
<x>110</x>
<y>140</y>
<width>181</width>
<height>25</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_14">
<property name="geometry">
<rect>
<x>230</x>
<y>186</y>
<width>41</width>
<height>19</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>ms</string>
</property>
</widget>
<widget class="QLabel" name="label_6">
<property name="geometry">
<rect>
<x>30</x>
<y>101</y>
<width>69</width>
<height>19</height>
</rect>
</property>
<property name="text">
<string>波特率</string>
</property>
<property name="buddy">
<cstring>cb_baund</cstring>
</property>
</widget>
<widget class="QLineEdit" name="delay_timeout">
<property name="geometry">
<rect>
<x>110</x>
<y>183</y>
<width>113</width>
<height>30</height>
</rect>
</property>
</widget>
<widget class="QComboBox" name="cb_type">
<property name="geometry">
<rect>
<x>110</x>
<y>20</y>
<width>181</width>
<height>25</height>
</rect>
</property>
</widget>
<widget class="QComboBox" name="cb_parity">
<property name="geometry">
<rect>
<x>420</x>
<y>140</y>
<width>201</width>
<height>25</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="slave_id">
<property name="geometry">
<rect>
<x>420</x>
<y>20</y>
<width>201</width>
<height>30</height>
</rect>
</property>
</widget>
<widget class="QComboBox" name="cb_serialport">
<property name="geometry">
<rect>
<x>110</x>
<y>60</y>
<width>511</width>
<height>25</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>340</x>
<y>20</y>
<width>69</width>
<height>19</height>
</rect>
</property>
<property name="text">
<string>从机地址</string>
</property>
<property name="buddy">
<cstring>slave_id</cstring>
</property>
</widget>
<widget class="QComboBox" name="cb_baund">
<property name="geometry">
<rect>
<x>110</x>
<y>101</y>
<width>181</width>
<height>25</height>
</rect>
</property>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -9,9 +9,16 @@
#include <QToolBar> #include <QToolBar>
#include <QLabel> #include <QLabel>
#include <QGraphicsDropShadowEffect> #include <QGraphicsDropShadowEffect>
#include <QMessageBox>
#include <QSizePolicy>
#include <QFontDatabase>
#include "libmodbus/modbus.h" #include "libmodbus/modbus.h"
#include "customwidget.h"
#include "formserialportsettingdialog.h"
#define _DEBUG_VSPD_ #define _DEBUG_VSPD_
#define TH08D_TEMPERATURE_EQUIPMENT_81_00_09 40000 #define TH08D_TEMPERATURE_EQUIPMENT_81_00_09 40000
@ -100,13 +107,10 @@ MainWindow::MainWindow(QWidget *parent)
m_modbus_slave_id = 1; m_modbus_slave_id = 1;
InitializeUI(); InitializeUI();
InitializeModbus();
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
{ {
delete ui;
if (m_pModbus) if (m_pModbus)
{ {
modbus_close(m_pModbus); modbus_close(m_pModbus);
@ -126,6 +130,7 @@ MainWindow::~MainWindow()
delete m_pSettings; delete m_pSettings;
m_pSettings = nullptr; m_pSettings = nullptr;
} }
delete ui;
} }
void MainWindow::getConfiguration(QString iniFilePath) void MainWindow::getConfiguration(QString iniFilePath)
@ -197,23 +202,41 @@ void MainWindow::getConfiguration(QString iniFilePath)
bool MainWindow::InitializeUI() bool MainWindow::InitializeUI()
{ {
#ifndef NDEBUG
this->showMaximized();
#endif
//初始化窗口边框 //初始化窗口边框
this->setAttribute(Qt::WA_TranslucentBackground, true); QWidget *centralWidget = this->centralWidget(); // new QWidget(this);
this->setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(this);
shadow->setOffset(0, 0);
shadow->setColor(QColor("#444444"));
shadow->setBlurRadius(16);
// ui->w_bg->setGraphicsEffect(shadow);
//ui->lay_bg->setMargin(12);
QWidget *centralWidget = new QWidget(this);
QGridLayout *mainLayout = new QGridLayout(centralWidget); QGridLayout *mainLayout = new QGridLayout(centralWidget);
this->setStyleSheet("background-color: white;");
//this->setProperty("canMove",true);
//设置窗体透明
this->setAttribute(Qt::WA_TranslucentBackground, true);
//设置无边框
this->setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
//实例阴影shadow
QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(this);
//设置阴影距离
shadow->setOffset(0, 0);
//设置阴影颜色
shadow->setColor(QColor(44,44,44));
//设置阴影圆角
shadow->setBlurRadius(16);
//给嵌套QDialog设置阴影
ui->centralwidget->setGraphicsEffect(shadow);
//给垂直布局器设置边距(此步很重要, 设置宽度为阴影的宽度)
//->setMargin(12);
// 创建2行4列布局共8个控件示例 // 创建2行4列布局共8个控件示例
for(int row=0; row<2; ++row) for(int row=0; row<2; ++row)
{ {
for(int col=0; col<4; ++col) for(int col=0; col<4; ++col)
{ {
#if 0
QLabel *label = new QLabel(QString("Cell %1-%2").arg(row).arg(col),this); QLabel *label = new QLabel(QString("Cell %1-%2").arg(row).arg(col),this);
label->setStyleSheet("background-color: rgb(192,192,192);" label->setStyleSheet("background-color: rgb(192,192,192);"
"color: #333333;" "color: #333333;"
@ -224,37 +247,88 @@ bool MainWindow::InitializeUI()
label->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); label->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
mainLayout->addWidget(label, row, col); mainLayout->addWidget(label, row, col);
m_panel_labels.push_back(label); m_panel_labels.push_back(label);
#endif
CustomWidget* pWidget = new CustomWidget(this);
mainLayout->addWidget(pWidget, row, col);
} }
} }
// 设置布局的间距和边距 // 设置布局的间距和边距
mainLayout->setSpacing(5); mainLayout->setSpacing(5);
//mainLayout->setContentsMargins(10, 40, 10, 10); // 顶部留出工具栏空间 //mainLayout->setContentsMargins(10, 40, 10, 10); // 顶部留出工具栏空间
setCentralWidget(centralWidget); //setCentralWidget(centralWidget);
QToolBar *toolBar = new QToolBar(this); QToolBar *toolBar = new QToolBar(this);
toolBar->setMovable(false); toolBar->setMovable(false);
toolBar->setToolButtonStyle(Qt::ToolButtonIconOnly);
toolBar->setIconSize(QSize(64,64)); toolBar->setIconSize(QSize(64,64));
// 设置按钮悬停效果(通过样式表)
// toolBar->setStyleSheet(
// "QToolButton { background: transparent; border: none; }"
// "QToolButton:hover { background: #e0e0e0; border-radius: 4px; }"
// );
// 添加工具栏按钮 // 添加工具栏按钮
QAction *actionRead = new QAction(QIcon(":/icons/modular.png"), tr("Read"), this); QAction *actionRead = new QAction(QIcon(":/icons/modular.png"), tr("Read"), this);
actionRead->setToolTip(tr("Read Data")); actionRead->setToolTip(tr("Read Data"));
QAction *actionSetting = new QAction(QIcon(":/icons/setting.png"), tr("Setting"), this);
actionSetting->setToolTip(tr("Setting Modbud Port"));
QAction *actionClose = new QAction(QIcon(":/icons/close.png"), tr("Close"), this); QAction *actionClose = new QAction(QIcon(":/icons/close.png"), tr("Close"), this);
actionClose->setToolTip(tr("Close Application")); actionClose->setToolTip(tr("Close Application"));
//添加按钮
toolBar->addAction(actionRead); toolBar->addAction(actionRead);
toolBar->addSeparator(); toolBar->addSeparator();
toolBar->addAction(actionClose);
// 添加间隔控件
QWidget *spacer = new QWidget();
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
toolBar->addWidget(spacer);
// 添加中央标签
QLabel *label = new QLabel(tr("综合电源柜监测"), this);
// 加载字体
int fontId = QFontDatabase::addApplicationFont(":/fonts/Alimama_DongFangDaKai_Regular.ttf");
if (fontId == -1)
{
qDebug() << "字体加载失败";
return -1;
}
//QFont customFont("Alimama DongFangDaKai", 48);
//customFont.setBold(true);
//label->setFont(customFont);
//label->setStyleSheet("color: #2E86C1;");
label->setStyleSheet(
"QLabel {"
" font-family: 'Alimama DongFangDaKai';" // 需确保字体已加载
" font-size: 52px;"
" color: #2E86C1;"
//" font-weight: bold;"
"}"
);
toolBar->addWidget(label);
QWidget *spacerWidget = new QWidget();
spacerWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
toolBar->addWidget(spacerWidget);
toolBar->addAction(actionSetting);
toolBar->addSeparator(); toolBar->addSeparator();
// 将工具栏定位到窗口顶部 toolBar->addAction(actionClose);
// 将工具栏定位到窗口顶部·
addToolBar(Qt::TopToolBarArea, toolBar); addToolBar(Qt::TopToolBarArea, toolBar);
connect(actionClose, &QAction::triggered, this, &QMainWindow::close); connect(actionClose, &QAction::triggered, this, &QMainWindow::close);
connect(actionSetting, &QAction::triggered, this, &MainWindow::SettingSerialPort);
connect(actionRead, &QAction::triggered, this, &MainWindow::ReadSerialPortData); connect(actionRead, &QAction::triggered, this, &MainWindow::ReadSerialPortData);
return false; ui->statusbar->showMessage(tr("Ready"), 0);
return true;
} }
bool MainWindow::InitializeModbus() bool MainWindow::InitializeModbus()
@ -339,6 +413,8 @@ bool MainWindow::InitializeTcp()
bool MainWindow::readRegister(int addr,int nb,uint16_t* dest) bool MainWindow::readRegister(int addr,int nb,uint16_t* dest)
{ {
InitializeModbus();
for (auto it = m_SlaveData.begin(); it != m_SlaveData.end(); ++it) for (auto it = m_SlaveData.begin(); it != m_SlaveData.end(); ++it)
{ {
SlaveItem* pItem = (SlaveItem*)(*it); SlaveItem* pItem = (SlaveItem*)(*it);
@ -367,10 +443,11 @@ bool MainWindow::readRegister(int addr,int nb,uint16_t* dest)
{ {
TemperatureData* pData = (TemperatureData*)pDevice; TemperatureData* pData = (TemperatureData*)pDevice;
assert(pData); assert(pData);
QString value;
if (pData->bDecodeTemp) if (pData->bDecodeTemp)
{ {
//ui->txt_content_1->append(QString(tr("温度:%1\n湿度: %2\n露点: %3\n")).arg(pData->TempValue).arg(pData->HumidityValue).arg(pData->DewPointValue)); //ui->txt_content_1->append(QString(tr("温度:%1\n湿度: %2\n露点: %3\n")).arg(pData->TempValue).arg(pData->HumidityValue).arg(pData->DewPointValue));
m_panel_labels[0]->setText(QString(tr("温度: %1\n湿度: %2\n露点: %3\n")).arg(pData->TempValue).arg(pData->HumidityValue).arg(pData->DewPointValue)); //m_panel_labels[0]->setText(QString(tr("温度: %1\n湿度: %2\n露点: %3\n")).arg(pData->TempValue).arg(pData->HumidityValue).arg(pData->DewPointValue));
} }
if (pData->bDecodeAlarm) if (pData->bDecodeAlarm)
{ {
@ -427,3 +504,15 @@ void MainWindow::ReadSerialPortData()
readRegister(0,0,0); readRegister(0,0,0);
} }
void MainWindow::SettingSerialPort()
{
FormSerialPortSettingDialog* dlg = new FormSerialPortSettingDialog(this);
dlg->setWindowFlags(dlg->windowFlags()&~(Qt::WindowMinMaxButtonsHint|Qt::WindowContextHelpButtonHint));
//dlg.setModal(true);
//dlg->show();
if(dlg->exec() == QDialog::Accepted)
QMessageBox::information(this, "OK Clicked", "Button 1 was clicked!");
else
QMessageBox::information(this, "Cancel Clicked", "Cancel was clicked!");
}

View File

@ -103,6 +103,7 @@ protected:
private slots: private slots:
void ReadSerialPortData(); void ReadSerialPortData();
void SettingSerialPort();
signals: signals:
// 处理进度信号 // 处理进度信号

View File

@ -24,5 +24,6 @@
<file>icons/umbrella.png</file> <file>icons/umbrella.png</file>
<file>icons/up.png</file> <file>icons/up.png</file>
<file>icons/warn.png</file> <file>icons/warn.png</file>
<file>fonts/Alimama_DongFangDaKai_Regular.ttf</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -0,0 +1,416 @@
#pragma execution_character_set("utf-8")
#include "battery.h"
#include "qpainter.h"
#include <QPainterPath>
#include "qtimer.h"
//#include "qdebug.h"
Battery::Battery(QWidget *parent) : QWidget(parent)
{
minValue = 0;
maxValue = 100;
value = 0;
alarmValue = 30;
step = 0.5;
borderRadius = 8;
bgRadius = 5;
headRadius = 3;
borderColorStart = QColor(100, 100, 100);
borderColorEnd = QColor(80, 80, 80);
alarmColorStart = QColor(250, 118, 113);
alarmColorEnd = QColor(204, 38, 38);
normalColorStart = QColor(50, 205, 51);
normalColorEnd = QColor(60, 179, 133);
isForward = false;
currentValue = 0;
timer = new QTimer(this);
timer->setInterval(10);
connect(timer, SIGNAL(timeout()), this, SLOT(updateValue()));
}
Battery::~Battery()
{
if (timer->isActive())
{
timer->stop();
}
}
void Battery::paintEvent(QPaintEvent *)
{
//绘制准备工作,启用反锯齿
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
//绘制边框
drawBorder(&painter);
//绘制背景
drawBg(&painter);
//绘制头部
drawHead(&painter);
}
void Battery::drawBorder(QPainter *painter)
{
painter->save();
double headWidth = width() / 10;
double batteryWidth = width() - headWidth;
//绘制电池边框
QPointF topLeft(5, 5);
QPointF bottomRight(batteryWidth, height() - 5);
batteryRect = QRectF(topLeft, bottomRight);
painter->setPen(QPen(borderColorStart, 5));
painter->setBrush(Qt::NoBrush);
painter->drawRoundedRect(batteryRect, borderRadius, borderRadius);
painter->restore();
}
void Battery::drawBg(QPainter *painter)
{
painter->save();
QLinearGradient batteryGradient(QPointF(0, 0), QPointF(0, height()));
if (currentValue <= alarmValue)
{
batteryGradient.setColorAt(0.0, alarmColorStart);
batteryGradient.setColorAt(1.0, alarmColorEnd);
}
else
{
batteryGradient.setColorAt(0.0, normalColorStart);
batteryGradient.setColorAt(1.0, normalColorEnd);
}
int margin = qMin(width(), height()) / 20;
double unit = (batteryRect.width() - (margin * 2)) / 100;
double width = currentValue * unit;
QPointF topLeft(batteryRect.topLeft().x() + margin, batteryRect.topLeft().y() + margin);
QPointF bottomRight(width + margin + 5, batteryRect.bottomRight().y() - margin);
QRectF rect(topLeft, bottomRight);
painter->setPen(Qt::NoPen);
painter->setBrush(batteryGradient);
painter->drawRoundedRect(rect, bgRadius, bgRadius);
painter->restore();
}
void Battery::drawHead(QPainter *painter)
{
painter->save();
QPointF headRectTopLeft(batteryRect.topRight().x(), height() / 3);
QPointF headRectBottomRight(width(), height() - height() / 3);
QRectF headRect(headRectTopLeft, headRectBottomRight);
QLinearGradient headRectGradient(headRect.topLeft(), headRect.bottomLeft());
headRectGradient.setColorAt(0.0, borderColorStart);
headRectGradient.setColorAt(1.0, borderColorEnd);
painter->setPen(Qt::NoPen);
painter->setBrush(headRectGradient);
painter->drawRoundedRect(headRect, headRadius, headRadius);
painter->restore();
}
void Battery::updateValue()
{
if (isForward)
{
currentValue -= step;
if (currentValue <= value)
{
timer->stop();
}
}
else
{
currentValue += step;
if (currentValue >= value)
{
timer->stop();
}
}
this->update();
}
double Battery::getMinValue() const
{
return this->minValue;
}
double Battery::getMaxValue() const
{
return this->maxValue;
}
double Battery::getValue() const
{
return this->value;
}
double Battery::getAlarmValue() const
{
return this->alarmValue;
}
double Battery::getStep() const
{
return this->step;
}
int Battery::getBorderRadius() const
{
return this->borderRadius;
}
int Battery::getBgRadius() const
{
return this->bgRadius;
}
int Battery::getHeadRadius() const
{
return this->headRadius;
}
QColor Battery::getBorderColorStart() const
{
return this->borderColorStart;
}
QColor Battery::getBorderColorEnd() const
{
return this->borderColorEnd;
}
QColor Battery::getAlarmColorStart() const
{
return this->alarmColorStart;
}
QColor Battery::getAlarmColorEnd() const
{
return this->alarmColorEnd;
}
QColor Battery::getNormalColorStart() const
{
return this->normalColorStart;
}
QColor Battery::getNormalColorEnd() const
{
return this->normalColorEnd;
}
QSize Battery::sizeHint() const
{
return QSize(150, 80);
}
QSize Battery::minimumSizeHint() const
{
return QSize(30, 10);
}
void Battery::setRange(double minValue, double maxValue)
{
//如果最小值大于或者等于最大值则不设置
if (minValue >= maxValue)
{
return;
}
this->minValue = minValue;
this->maxValue = maxValue;
//如果目标值不在范围值内,则重新设置目标值
if (value < minValue || value > maxValue)
{
setValue(value);
}
this->update();
}
void Battery::setRange(int minValue, int maxValue)
{
setRange((double)minValue, (double)maxValue);
}
void Battery::setMinValue(double minValue)
{
setRange(minValue, maxValue);
}
void Battery::setMaxValue(double maxValue)
{
setRange(minValue, maxValue);
}
void Battery::setValue(double value)
{
//值和当前值一致则无需处理
if (value == this->value)
{
return;
}
//值小于最小值则取最小值,大于最大值则取最大值
if (value < minValue)
{
value = minValue;
}
else if (value > maxValue)
{
value = maxValue;
}
emit valueChanged(value);
this->value = value;
if (value > currentValue)
{
isForward = false;
}
else if (value < currentValue)
{
isForward = true;
}
else
{
return ;
}
timer->start();
this->update();
}
void Battery::setValue(int value)
{
setValue((double)value);
}
void Battery::setAlarmValue(double alarmValue)
{
if (this->alarmValue != alarmValue)
{
this->alarmValue = alarmValue;
this->update();
}
}
void Battery::setAlarmValue(int alarmValue)
{
setAlarmValue((double)alarmValue);
}
void Battery::setStep(double step)
{
if (this->step != step)
{
this->step = step;
this->update();
}
}
void Battery::setStep(int step)
{
setStep((double)step);
}
void Battery::setBorderRadius(int borderRadius)
{
if (this->borderRadius != borderRadius)
{
this->borderRadius = borderRadius;
this->update();
}
}
void Battery::setBgRadius(int bgRadius)
{
if (this->bgRadius != bgRadius)
{
this->bgRadius = bgRadius;
this->update();
}
}
void Battery::setHeadRadius(int headRadius)
{
if (this->headRadius != headRadius)
{
this->headRadius = headRadius;
this->update();
}
}
void Battery::setBorderColorStart(const QColor &borderColorStart)
{
if (this->borderColorStart != borderColorStart)
{
this->borderColorStart = borderColorStart;
this->update();
}
}
void Battery::setBorderColorEnd(const QColor &borderColorEnd)
{
if (this->borderColorEnd != borderColorEnd)
{
this->borderColorEnd = borderColorEnd;
this->update();
}
}
void Battery::setAlarmColorStart(const QColor &alarmColorStart)
{
if (this->alarmColorStart != alarmColorStart)
{
this->alarmColorStart = alarmColorStart;
this->update();
}
}
void Battery::setAlarmColorEnd(const QColor &alarmColorEnd)
{
if (this->alarmColorEnd != alarmColorEnd)
{
this->alarmColorEnd = alarmColorEnd;
this->update();
}
}
void Battery::setNormalColorStart(const QColor &normalColorStart)
{
if (this->normalColorStart != normalColorStart)
{
this->normalColorStart = normalColorStart;
this->update();
}
}
void Battery::setNormalColorEnd(const QColor &normalColorEnd)
{
if (this->normalColorEnd != normalColorEnd)
{
this->normalColorEnd = normalColorEnd;
this->update();
}
}

View File

@ -0,0 +1,155 @@
#ifndef BATTERY_H
#define BATTERY_H
/**
* :feiyangqingyun(QQ:517216493) 2016-10-23
* 1:,
* 2:
* 3:
* 4:
* 5:
* 6://
*/
#include <QWidget>
#include <QPainterPath>
#ifdef quc
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
#include <QtDesigner/QDesignerExportWidget>
#else
#include <QtUiPlugin/QDesignerExportWidget>
#endif
class QDESIGNER_WIDGET_EXPORT Battery : public QWidget
#else
class Battery : public QWidget
#endif
{
Q_OBJECT
Q_PROPERTY(double minValue READ getMinValue WRITE setMinValue)
Q_PROPERTY(double maxValue READ getMaxValue WRITE setMaxValue)
Q_PROPERTY(double value READ getValue WRITE setValue)
Q_PROPERTY(double alarmValue READ getAlarmValue WRITE setAlarmValue)
Q_PROPERTY(double step READ getStep WRITE setStep)
Q_PROPERTY(int borderRadius READ getBorderRadius WRITE setBorderRadius)
Q_PROPERTY(int bgRadius READ getBgRadius WRITE setBgRadius)
Q_PROPERTY(int headRadius READ getHeadRadius WRITE setHeadRadius)
Q_PROPERTY(QColor borderColorStart READ getBorderColorStart WRITE setBorderColorStart)
Q_PROPERTY(QColor borderColorEnd READ getBorderColorEnd WRITE setBorderColorEnd)
Q_PROPERTY(QColor alarmColorStart READ getAlarmColorStart WRITE setAlarmColorStart)
Q_PROPERTY(QColor alarmColorEnd READ getAlarmColorEnd WRITE setAlarmColorEnd)
Q_PROPERTY(QColor normalColorStart READ getNormalColorStart WRITE setNormalColorStart)
Q_PROPERTY(QColor normalColorEnd READ getNormalColorEnd WRITE setNormalColorEnd)
public:
explicit Battery(QWidget *parent = 0);
~Battery();
protected:
void paintEvent(QPaintEvent *);
void drawBorder(QPainter *painter);
void drawBg(QPainter *painter);
void drawHead(QPainter *painter);
private slots:
void updateValue();
private:
double minValue; //最小值
double maxValue; //最大值
double value; //目标电量
double alarmValue; //电池电量警戒值
double step; //每次移动的步长
int borderRadius; //边框圆角角度
int bgRadius; //背景进度圆角角度
int headRadius; //头部圆角角度
QColor borderColorStart; //边框渐变开始颜色
QColor borderColorEnd; //边框渐变结束颜色
QColor alarmColorStart; //电池低电量时的渐变开始颜色
QColor alarmColorEnd; //电池低电量时的渐变结束颜色
QColor normalColorStart; //电池正常电量时的渐变开始颜色
QColor normalColorEnd; //电池正常电量时的渐变结束颜色
bool isForward; //是否往前移
double currentValue; //当前电量
QRectF batteryRect; //电池主体区域
QTimer *timer; //绘制定时器
public:
double getMinValue() const;
double getMaxValue() const;
double getValue() const;
double getAlarmValue() const;
double getStep() const;
int getBorderRadius() const;
int getBgRadius() const;
int getHeadRadius() const;
QColor getBorderColorStart() const;
QColor getBorderColorEnd() const;
QColor getAlarmColorStart() const;
QColor getAlarmColorEnd() const;
QColor getNormalColorStart() const;
QColor getNormalColorEnd() const;
QSize sizeHint() const;
QSize minimumSizeHint() const;
public Q_SLOTS:
//设置范围值
void setRange(double minValue, double maxValue);
void setRange(int minValue, int maxValue);
//设置最大最小值
void setMinValue(double minValue);
void setMaxValue(double maxValue);
//设置电池电量值
void setValue(double value);
void setValue(int value);
//设置电池电量警戒值
void setAlarmValue(double alarmValue);
void setAlarmValue(int alarmValue);
//设置步长
void setStep(double step);
void setStep(int step);
//设置边框圆角角度
void setBorderRadius(int borderRadius);
//设置背景圆角角度
void setBgRadius(int bgRadius);
//设置头部圆角角度
void setHeadRadius(int headRadius);
//设置边框渐变颜色
void setBorderColorStart(const QColor &borderColorStart);
void setBorderColorEnd(const QColor &borderColorEnd);
//设置电池电量报警时的渐变颜色
void setAlarmColorStart(const QColor &alarmColorStart);
void setAlarmColorEnd(const QColor &alarmColorEnd);
//设置电池电量正常时的渐变颜色
void setNormalColorStart(const QColor &normalColorStart);
void setNormalColorEnd(const QColor &normalColorEnd);
Q_SIGNALS:
void valueChanged(double value);
};
#endif // BATTERY_H

View File

@ -0,0 +1,21 @@
#pragma execution_character_set("utf-8")
#include "frmbattery.h"
#include "ui_frmbattery.h"
frmBattery::frmBattery(QWidget *parent) : QWidget(parent), ui(new Ui::frmBattery)
{
ui->setupUi(this);
this->initForm();
}
frmBattery::~frmBattery()
{
delete ui;
}
void frmBattery::initForm()
{
connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), ui->battery, SLOT(setValue(int)));
ui->horizontalSlider->setValue(30);
}

View File

@ -0,0 +1,27 @@
#ifndef FRMBATTERY_H
#define FRMBATTERY_H
#include <QWidget>
#include <QPainterPath>
namespace Ui
{
class frmBattery;
}
class frmBattery : public QWidget
{
Q_OBJECT
public:
explicit frmBattery(QWidget *parent = 0);
~frmBattery();
private:
Ui::frmBattery *ui;
private slots:
void initForm();
};
#endif // FRMBATTERY_H

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>frmBattery</class>
<widget class="QWidget" name="frmBattery">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="Battery" name="battery" native="true">
<property name="geometry">
<rect>
<x>9</x>
<y>9</y>
<width>482</width>
<height>257</height>
</rect>
</property>
</widget>
<widget class="QSlider" name="horizontalSlider">
<property name="geometry">
<rect>
<x>9</x>
<y>272</y>
<width>481</width>
<height>19</height>
</rect>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="invertedControls">
<bool>false</bool>
</property>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>Battery</class>
<extends>QWidget</extends>
<header>battery.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,99 @@
#pragma execution_character_set("utf-8")
#include "frmgaugepanel.h"
#include "ui_frmgaugepanel.h"
#include "qdebug.h"
frmGaugePanel::frmGaugePanel(QWidget *parent) : QWidget(parent), ui(new Ui::frmGaugePanel)
{
ui->setupUi(this);
this->initForm();
}
frmGaugePanel::~frmGaugePanel()
{
delete ui;
}
void frmGaugePanel::initForm()
{
#if 0
ui->horizontalSlider1->setVisible(false);
ui->horizontalSlider2->setVisible(false);
ui->horizontalSlider3->setVisible(false);
ui->horizontalSlider4->setVisible(false);
ui->horizontalSlider5->setVisible(false);
ui->horizontalSlider6->setVisible(false);
#endif
//设置样式
QStringList list;
list.append("#widget{background:#222939;}");
list.append("GaugePanel{qproperty-ringColor:#393F4D;qproperty-scaleColor:#03B7C9;"
"qproperty-pointerColor:#03B7C9;qproperty-textColor:#EEEEEE;}");
ui->widget->setStyleSheet(list.join(""));
//设置单位
ui->gaugePanel1->setUnit("V");
ui->gaugePanel2->setUnit("A");
ui->gaugePanel3->setUnit("m");
ui->gaugePanel4->setUnit("kW");
ui->gaugePanel5->setUnit("kWh");
ui->gaugePanel6->setUnit("Hz");
//设置名称
ui->gaugePanel1->setText("电压");
ui->gaugePanel2->setText("电流");
ui->gaugePanel3->setText("水位");
ui->gaugePanel4->setText("有功功率");
ui->gaugePanel5->setText("有功电能");
ui->gaugePanel6->setText("电网频率");
//设置小数点
ui->gaugePanel3->setPrecision(1);
ui->gaugePanel4->setPrecision(2);
ui->gaugePanel5->setPrecision(1);
ui->gaugePanel3->setScalePrecision(1);
//设置启用动画
ui->gaugePanel4->setAnimation(true);
ui->gaugePanel5->setAnimation(true);
ui->gaugePanel5->setAnimationStep(0.2);
//设置范围值
ui->gaugePanel1->setRange(0, 500);
ui->gaugePanel2->setRange(0, 60);
ui->gaugePanel3->setRange(0, 2);
ui->gaugePanel4->setRange(0, 50);
ui->gaugePanel5->setRange(0, 70);
ui->gaugePanel6->setRange(0, 100);
ui->horizontalSlider1->setRange(0, 500);
ui->horizontalSlider2->setRange(0, 60);
ui->horizontalSlider3->setRange(0, 200);
ui->horizontalSlider4->setRange(0, 50);
ui->horizontalSlider5->setRange(0, 70);
ui->horizontalSlider6->setRange(0, 100);
//绑定滑块
connect(ui->horizontalSlider1, SIGNAL(valueChanged(int)), ui->gaugePanel1, SLOT(setValue(int)));
connect(ui->horizontalSlider2, SIGNAL(valueChanged(int)), ui->gaugePanel2, SLOT(setValue(int)));
//connect(ui->horizontalSlider3, SIGNAL(valueChanged(int)), ui->gaugePanel3, SLOT(setValue(int)));
connect(ui->horizontalSlider4, SIGNAL(valueChanged(int)), ui->gaugePanel4, SLOT(setValue(int)));
connect(ui->horizontalSlider5, SIGNAL(valueChanged(int)), ui->gaugePanel5, SLOT(setValue(int)));
connect(ui->horizontalSlider6, SIGNAL(valueChanged(int)), ui->gaugePanel6, SLOT(setValue(int)));
//设置初始值
ui->horizontalSlider1->setValue(220);
ui->horizontalSlider2->setValue(32);
ui->horizontalSlider3->setValue(150);
ui->horizontalSlider4->setValue(6.34);
ui->horizontalSlider5->setValue(6.28);
ui->horizontalSlider6->setValue(50);
}
void frmGaugePanel::on_horizontalSlider3_valueChanged(int value)
{
double v = (double)value / 100;
ui->gaugePanel3->setValue(v);
}

View File

@ -0,0 +1,27 @@
#ifndef FRMGAUGEPANEL_H
#define FRMGAUGEPANEL_H
#include <QWidget>
#include <QPainterPath>
namespace Ui {
class frmGaugePanel;
}
class frmGaugePanel : public QWidget
{
Q_OBJECT
public:
explicit frmGaugePanel(QWidget *parent = 0);
~frmGaugePanel();
private:
Ui::frmGaugePanel *ui;
private slots:
void initForm();
void on_horizontalSlider3_valueChanged(int value);
};
#endif // FRMGAUGEPANEL_H

View File

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>frmGaugePanel</class>
<widget class="QWidget" name="frmGaugePanel">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="GaugePanel" name="gaugePanel1" native="true"/>
</item>
<item row="0" column="2">
<widget class="GaugePanel" name="gaugePanel3" native="true"/>
</item>
<item row="2" column="0">
<widget class="GaugePanel" name="gaugePanel4" native="true"/>
</item>
<item row="0" column="1">
<widget class="GaugePanel" name="gaugePanel2" native="true"/>
</item>
<item row="2" column="2">
<widget class="GaugePanel" name="gaugePanel6" native="true"/>
</item>
<item row="2" column="1">
<widget class="GaugePanel" name="gaugePanel5" native="true"/>
</item>
<item row="1" column="2">
<widget class="QSlider" name="horizontalSlider3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSlider" name="horizontalSlider2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QSlider" name="horizontalSlider1">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QSlider" name="horizontalSlider4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSlider" name="horizontalSlider5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QSlider" name="horizontalSlider6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>GaugePanel</class>
<extends>QWidget</extends>
<header>gaugepanel.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,568 @@
#pragma execution_character_set("utf-8")
#include "gaugepanel.h"
#include "qpainter.h"
#include <QPainterPath>
#include "qmath.h"
#include "qtimer.h"
#include "qlcdnumber.h"
#include "qdebug.h"
GaugePanel::GaugePanel(QWidget *parent) : QWidget(parent)
{
minValue = 0;
maxValue = 100;
value = 0;
precision = 0;
scalePrecision = 0;
scaleMajor = 10;
scaleMinor = 5;
startAngle = 45;
endAngle = 45;
animation = false;
animationStep = 0.5;
ringWidth = 10;
ringColor = QColor(54, 192, 254);
scaleColor = QColor(34, 163, 169);
pointerColor = QColor(34, 163, 169);
bgColor = Qt::transparent;
textColor = QColor(50, 50, 50);
unit = "V";
text = "电压";
reverse = false;
currentValue = 0;
timer = new QTimer(this);
timer->setInterval(10);
connect(timer, SIGNAL(timeout()), this, SLOT(updateValue()));
//setFont(QFont("Arial", 9));
}
GaugePanel::~GaugePanel()
{
if (timer->isActive())
{
timer->stop();
}
}
void GaugePanel::paintEvent(QPaintEvent *)
{
int width = this->width();
int height = this->height();
int side = qMin(width, height);
//绘制准备工作,启用反锯齿,平移坐标轴中心,等比例缩放
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
//绘制背景
if (bgColor != Qt::transparent)
{
painter.setPen(Qt::NoPen);
painter.fillRect(this->rect(), bgColor);
}
painter.translate(width / 2, height / 2);
painter.scale(side / 200.0, side / 200.0);
//绘制圆环
drawRing(&painter);
//绘制刻度线
drawScale(&painter);
//绘制刻度值
drawScaleNum(&painter);
//绘制指示器
drawPointer(&painter);
//绘制当前值
drawValue(&painter);
}
void GaugePanel::drawRing(QPainter *painter)
{
int radius = 70;
painter->save();
QPen pen;
pen.setCapStyle(Qt::FlatCap);
pen.setWidthF(ringWidth);
pen.setColor(ringColor);
painter->setPen(pen);
radius = radius - ringWidth;
QRectF rect = QRectF(-radius, -radius, radius * 2, radius * 2);
double angleAll = 360.0 - startAngle - endAngle;
painter->drawArc(rect, (270 - startAngle - angleAll) * 16, angleAll * 16);
painter->restore();
}
void GaugePanel::drawScale(QPainter *painter)
{
int radius = 80;
painter->save();
painter->rotate(startAngle);
int steps = (scaleMajor * scaleMinor);
double angleStep = (360.0 - startAngle - endAngle) / steps;
QPen pen;
pen.setCapStyle(Qt::RoundCap);
pen.setColor(scaleColor);
for (int i = 0; i <= steps; i++)
{
if (i % scaleMinor == 0)
{
pen.setWidthF(1.5);
painter->setPen(pen);
painter->drawLine(0, radius - 8, 0, radius + 5);
}
else
{
pen.setWidthF(0.5);
painter->setPen(pen);
painter->drawLine(0, radius - 8, 0, radius - 3);
}
painter->rotate(angleStep);
}
painter->restore();
}
void GaugePanel::drawScaleNum(QPainter *painter)
{
int radius = 95;
painter->save();
painter->setPen(scaleColor);
double startRad = (360 - startAngle - 90) * (M_PI / 180);
double deltaRad = (360 - startAngle - endAngle) * (M_PI / 180) / scaleMajor;
for (int i = 0; i <= scaleMajor; i++)
{
double sina = qSin(startRad - i * deltaRad);
double cosa = qCos(startRad - i * deltaRad);
double value = 1.0 * i * ((maxValue - minValue) / scaleMajor) + minValue;
QString strValue = QString("%1").arg((double)value, 0, 'f', scalePrecision);
double textWidth = fontMetrics().size(Qt::TextSingleLine,strValue).width();// .width(strValue);
double textHeight = fontMetrics().height();
int x = radius * cosa - textWidth / 2;
int y = -radius * sina + textHeight / 4;
painter->drawText(x, y, strValue);
}
painter->restore();
}
void GaugePanel::drawPointer(QPainter *painter)
{
int radius = 70;
painter->save();
painter->setPen(Qt::NoPen);
painter->setBrush(pointerColor);
QPolygon pts;
pts.setPoints(4, -5, 0, 0, -8, 5, 0, 0, radius);
painter->rotate(startAngle);
double degRotate = (360.0 - startAngle - endAngle) / (maxValue - minValue) * (currentValue - minValue);
painter->rotate(degRotate);
painter->drawConvexPolygon(pts);
painter->restore();
}
void GaugePanel::drawValue(QPainter *painter)
{
int radius = 100;
painter->save();
painter->setPen(textColor);
QFont font;
font.setPixelSize(15);
painter->setFont(font);
QString strValue = QString("%1").arg((double)currentValue, 0, 'f', precision);
strValue = QString("%1 %2").arg(strValue).arg(unit);
QRectF valueRect(-radius, radius / 3.5, radius * 2, radius / 3.5);
painter->drawText(valueRect, Qt::AlignCenter, strValue);
QRectF textRect(-radius, radius / 2.5, radius * 2, radius / 2.5);
font.setPixelSize(12);
painter->setFont(font);
painter->drawText(textRect, Qt::AlignCenter, text);
painter->restore();
}
void GaugePanel::updateValue()
{
if (!reverse)
{
if (currentValue >= value)
{
timer->stop();
}
else
{
currentValue += animationStep;
}
}
else
{
if (currentValue <= value)
{
timer->stop();
}
else
{
currentValue -= animationStep;
}
}
this->update();
}
double GaugePanel::getMinValue() const
{
return this->minValue;
}
double GaugePanel::getMaxValue() const
{
return this->maxValue;
}
double GaugePanel::getValue() const
{
return this->value;
}
int GaugePanel::getPrecision() const
{
return this->precision;
}
int GaugePanel::getScalePrecision() const
{
return this->scalePrecision;
}
int GaugePanel::getScaleMajor() const
{
return this->scaleMajor;
}
int GaugePanel::getScaleMinor() const
{
return this->scaleMinor;
}
int GaugePanel::getStartAngle() const
{
return this->startAngle;
}
int GaugePanel::getEndAngle() const
{
return this->endAngle;
}
bool GaugePanel::getAnimation() const
{
return this->animation;
}
double GaugePanel::getAnimationStep() const
{
return this->animationStep;
}
int GaugePanel::getRingWidth() const
{
return this->ringWidth;
}
QColor GaugePanel::getRingColor() const
{
return this->ringColor;
}
QColor GaugePanel::getScaleColor() const
{
return this->scaleColor;
}
QColor GaugePanel::getPointerColor() const
{
return this->pointerColor;
}
QColor GaugePanel::getBgColor() const
{
return this->bgColor;
}
QColor GaugePanel::getTextColor() const
{
return this->textColor;
}
QString GaugePanel::getUnit() const
{
return this->unit;
}
QString GaugePanel::getText() const
{
return this->text;
}
QSize GaugePanel::sizeHint() const
{
return QSize(200, 200);
}
QSize GaugePanel::minimumSizeHint() const
{
return QSize(50, 50);
}
void GaugePanel::setRange(double minValue, double maxValue)
{
//如果最小值大于或者等于最大值则不设置
if (minValue >= maxValue)
{
return;
}
this->minValue = minValue;
this->maxValue = maxValue;
//如果目标值不在范围值内,则重新设置目标值
if (value < minValue || value > maxValue)
{
setValue(value);
}
this->update();
}
void GaugePanel::setRange(int minValue, int maxValue)
{
setRange((double)minValue, (double)maxValue);
}
void GaugePanel::setMinValue(double minValue)
{
setRange(minValue, maxValue);
}
void GaugePanel::setMaxValue(double maxValue)
{
setRange(minValue, maxValue);
}
void GaugePanel::setValue(double value)
{
//值和当前值一致则无需处理
if (value == this->value)
{
return;
}
//值小于最小值则取最小值,大于最大值则取最大值
if (value < minValue)
{
value = minValue;
}
else if (value > maxValue)
{
value = maxValue;
}
if (value > this->value)
{
reverse = false;
}
else if (value < this->value)
{
reverse = true;
}
this->value = value;
emit valueChanged(value);
if (!animation)
{
currentValue = this->value;
this->update();
}
else
{
timer->start();
}
}
void GaugePanel::setValue(int value)
{
setValue((double)value);
}
void GaugePanel::setPrecision(int precision)
{
//最大精确度为 3
if (precision <= 3 && this->precision != precision)
{
this->precision = precision;
this->update();
}
}
void GaugePanel::setScalePrecision(int scalePrecision)
{
//最大精确度为 2
if (scalePrecision <= 2 && this->scalePrecision != scalePrecision)
{
this->scalePrecision = scalePrecision;
this->update();
}
}
void GaugePanel::setScaleMajor(int scaleMajor)
{
if (this->scaleMajor != scaleMajor)
{
this->scaleMajor = scaleMajor;
this->update();
}
}
void GaugePanel::setScaleMinor(int scaleMinor)
{
if (this->scaleMinor != scaleMinor)
{
this->scaleMinor = scaleMinor;
this->update();
}
}
void GaugePanel::setStartAngle(int startAngle)
{
if (this->startAngle != startAngle)
{
this->startAngle = startAngle;
this->update();
}
}
void GaugePanel::setEndAngle(int endAngle)
{
if (this->endAngle != endAngle)
{
this->endAngle = endAngle;
this->update();
}
}
void GaugePanel::setAnimation(bool animation)
{
if (this->animation != animation)
{
this->animation = animation;
this->update();
}
}
void GaugePanel::setAnimationStep(double animationStep)
{
if (this->animationStep != animationStep)
{
this->animationStep = animationStep;
this->update();
}
}
void GaugePanel::setRingWidth(int ringWidth)
{
if (this->ringWidth != ringWidth)
{
this->ringWidth = ringWidth;
this->update();
}
}
void GaugePanel::setRingColor(const QColor &ringColor)
{
if (this->ringColor != ringColor)
{
this->ringColor = ringColor;
this->update();
}
}
void GaugePanel::setScaleColor(const QColor &scaleColor)
{
if (this->scaleColor != scaleColor)
{
this->scaleColor = scaleColor;
this->update();
}
}
void GaugePanel::setPointerColor(const QColor &pointerColor)
{
if (this->pointerColor != pointerColor)
{
this->pointerColor = pointerColor;
this->update();
}
}
void GaugePanel::setBgColor(const QColor &bgColor)
{
if (this->bgColor != bgColor)
{
this->bgColor = bgColor;
this->update();
}
}
void GaugePanel::setTextColor(const QColor &textColor)
{
if (this->textColor != textColor)
{
this->textColor = textColor;
this->update();
}
}
void GaugePanel::setUnit(const QString &unit)
{
if (this->unit != unit)
{
this->unit = unit;
this->update();
}
}
void GaugePanel::setText(const QString &text)
{
if (this->text != text)
{
this->text = text;
this->update();
}
}

View File

@ -0,0 +1,182 @@
#ifndef GAUGEPANEL_H
#define GAUGEPANEL_H
/**
* :feiyangqingyun(QQ:517216493) 2019-7-3
* 1:,
* 2:+,3
* 3:/
* 4:/
* 5:
* 6:++
* 7:,
* 8:
*/
#include <QWidget>
#include <QPainterPath>
#ifdef quc
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
#include <QtDesigner/QDesignerExportWidget>
#else
#include <QtUiPlugin/QDesignerExportWidget>
#endif
class QDESIGNER_WIDGET_EXPORT GaugePanel : public QWidget
#else
class GaugePanel : public QWidget
#endif
{
Q_OBJECT
Q_PROPERTY(double minValue READ getMinValue WRITE setMinValue)
Q_PROPERTY(double maxValue READ getMaxValue WRITE setMaxValue)
Q_PROPERTY(double value READ getValue WRITE setValue)
Q_PROPERTY(int precision READ getPrecision WRITE setPrecision)
Q_PROPERTY(int scalePrecision READ getScalePrecision WRITE setScalePrecision)
Q_PROPERTY(int scaleMajor READ getScaleMajor WRITE setScaleMajor)
Q_PROPERTY(int scaleMinor READ getScaleMinor WRITE setScaleMinor)
Q_PROPERTY(int startAngle READ getStartAngle WRITE setStartAngle)
Q_PROPERTY(int endAngle READ getEndAngle WRITE setEndAngle)
Q_PROPERTY(bool animation READ getAnimation WRITE setAnimation)
Q_PROPERTY(double animationStep READ getAnimationStep WRITE setAnimationStep)
Q_PROPERTY(int ringWidth READ getRingWidth WRITE setRingWidth)
Q_PROPERTY(QColor ringColor READ getRingColor WRITE setRingColor)
Q_PROPERTY(QColor scaleColor READ getScaleColor WRITE setScaleColor)
Q_PROPERTY(QColor pointerColor READ getPointerColor WRITE setPointerColor)
Q_PROPERTY(QColor bgColor READ getBgColor WRITE setBgColor)
Q_PROPERTY(QColor textColor READ getTextColor WRITE setTextColor)
Q_PROPERTY(QString unit READ getUnit WRITE setUnit)
Q_PROPERTY(QString text READ getText WRITE setText)
public:
explicit GaugePanel(QWidget *parent = 0);
~GaugePanel();
protected:
void paintEvent(QPaintEvent *);
void drawRing(QPainter *painter);
void drawScale(QPainter *painter);
void drawScaleNum(QPainter *painter);
void drawPointer(QPainter *painter);
void drawValue(QPainter *painter);
private slots:
void updateValue();
private:
double minValue; //最小值
double maxValue; //最大值
double value; //目标值
int precision; //精确度,小数点后几位
int scalePrecision; //刻度尺精确度,小数点后几位
int scaleMajor; //大刻度数量
int scaleMinor; //小刻度数量
int startAngle; //开始旋转角度
int endAngle; //结束旋转角度
bool animation; //是否启用动画显示
double animationStep; //动画显示时步长
int ringWidth; //圆环宽度
QColor ringColor; //圆环颜色
QColor scaleColor; //刻度颜色
QColor pointerColor; //指针颜色
QColor bgColor; //背景颜色
QColor textColor; //文字颜色
QString unit; //单位
QString text; //描述文字
bool reverse; //是否往回走
double currentValue; //当前值
QTimer *timer; //定时器绘制动画
public:
double getMinValue() const;
double getMaxValue() const;
double getValue() const;
int getPrecision() const;
int getScalePrecision() const;
int getScaleMajor() const;
int getScaleMinor() const;
int getStartAngle() const;
int getEndAngle() const;
bool getAnimation() const;
double getAnimationStep() const;
int getRingWidth() const;
QColor getRingColor() const;
QColor getScaleColor() const;
QColor getPointerColor() const;
QColor getBgColor() const;
QColor getTextColor() const;
QString getUnit() const;
QString getText() const;
QSize sizeHint() const;
QSize minimumSizeHint() const;
public Q_SLOTS:
//设置范围值
void setRange(double minValue, double maxValue);
void setRange(int minValue, int maxValue);
//设置最大最小值
void setMinValue(double minValue);
void setMaxValue(double maxValue);
//设置目标值
void setValue(double value);
void setValue(int value);
//设置精确度
void setPrecision(int precision);
//设置刻度尺精确度
void setScalePrecision(int scalePrecision);
//设置主刻度数量
void setScaleMajor(int scaleMajor);
//设置小刻度数量
void setScaleMinor(int scaleMinor);
//设置开始旋转角度
void setStartAngle(int startAngle);
//设置结束旋转角度
void setEndAngle(int endAngle);
//设置是否启用动画显示
void setAnimation(bool animation);
//设置动画显示的步长
void setAnimationStep(double animationStep);
//设置圆环宽度+颜色
void setRingWidth(int ringWidth);
void setRingColor(const QColor &ringColor);
//设置刻度颜色
void setScaleColor(const QColor &scaleColor);
//设置指针颜色
void setPointerColor(const QColor &pointerColor);
//设置背景颜色
void setBgColor(const QColor &bgColor);
//设置文本颜色
void setTextColor(const QColor &textColor);
//设置单位
void setUnit(const QString &unit);
//设置中间描述文字
void setText(const QString &text);
Q_SIGNALS:
void valueChanged(int value);
};
#endif // GAUGEPANEL_H