Files
QT_wuhan_YT/widgets/paramcontrol.cpp
T
2026-10-14 09:59:42 +08:00

163 lines
5.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "paramcontrol.h"
#include "numpaddialog.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QKeyEvent>
#include "global.h"
ParamControl::ParamControl(const QString& name, const QString& unit,
double step, double min, double max,
bool withSave, bool withFactory, QWidget* parent)
: QWidget(parent), m_name(name), m_unit(unit),
m_step(step), m_min(min), m_max(max), m_value(min)
{
QVBoxLayout* lay = new QVBoxLayout(this);
lay->setContentsMargins(12, 8, 12, 8);
lay->setSpacing(6);
// 参数名
m_nameLabel = new QLabel(name, this);
m_nameLabel->setProperty("sub", true);
m_nameLabel->setStyleSheet(QString("color:%1;font-size:40px;").arg(C::TEXT_SUB));
lay->addWidget(m_nameLabel);
// 数值输入框 + 单位(同一行;框内只显示数值)
m_valRow = new QHBoxLayout();
m_valRow->setSpacing(12);
m_valueEdit = new QLineEdit(this);
m_valueEdit->setReadOnly(true);
m_valueEdit->setAlignment(Qt::AlignCenter);
m_valueEdit->setFocusPolicy(Qt::StrongFocus);
m_valueEdit->setFixedWidth(150); // 输入框长度(按需调整)
m_valueEdit->setStyleSheet("font-size:40px;font-weight:700;");
m_valueEdit->installEventFilter(this);
m_valRow->addStretch(0); // 行首弹性空间:setCentered(true) 时置 1,数值行即居中
m_valRow->addWidget(m_valueEdit);
m_unitLabel = new QLabel(unit, this);
m_unitLabel->setStyleSheet(QString("color:%1;font-size:40px;").arg(C::TEXT_SUB));
// 同一行右侧还有按钮时,给单位固定占位,保证各参数的按钮 x 一致
// (110 取全项目最长单位“L/min”在 40px 字号下的宽度约 101px)
if (withSave || withFactory)
m_unitLabel->setFixedWidth(110);
m_valRow->addWidget(m_unitLabel);
// 保存 / 恢复出厂值(可选):跟在单位后面,与输入框同一行、整体左对齐
if (withSave) {
m_save = new QPushButton("保存", this);
m_save->setProperty("variant", "primary");
m_save->setFixedSize(140, 60); // 固定宽高,不再随布局拉伸
connect(m_save, &QPushButton::clicked, this, &ParamControl::saveClicked);
m_valRow->addWidget(m_save);
}
if (withFactory) {
m_factory = new QPushButton("恢复出厂值", this);
m_factory->setMinimumHeight(56);
connect(m_factory, &QPushButton::clicked, this, &ParamControl::factoryResetClicked);
m_valRow->addWidget(m_factory);
}
m_valRow->addStretch(1);
lay->addLayout(m_valRow);
refresh();
}
void ParamControl::setValue(double v)
{
m_value = qBound(m_min, v, m_max);
refresh();
}
QWidget* ParamControl::editor() const
{
return m_valueEdit;
}
void ParamControl::setEnabled(bool enabled)
{
QWidget::setEnabled(enabled);
}
void ParamControl::setCentered(bool on)
{
m_nameLabel->setAlignment(on ? Qt::AlignCenter : (Qt::AlignLeft | Qt::AlignVCenter));
m_valRow->setStretch(0, on ? 1 : 0); // 行首弹性空间与行尾均分 → 整行居中(含保存按钮)
}
// 旋钮接口:steps > 0 调大、< 0 调小(每格 = m_step,自动钳位到 [min, max])
// 目前由数值框上的 ↑/↓ 键驱动,后续接面板机械旋钮也走这里
void ParamControl::adjustByKnob(int steps)
{
if (steps == 0)
return;
const double old = m_value;
setValue(old + steps * m_step);
if (m_value != old)
emit valueChanged(m_value);
}
// 点击数值框 / 回车 → 弹出数字键盘(面板靠左、不透明度 80%);↑/↓ → 每档加减一次
bool ParamControl::eventFilter(QObject* obj, QEvent* ev)
{
if (obj == m_valueEdit) {
if (ev->type() == QEvent::MouseButtonPress) {
openNumPad();
return true;
}
if (ev->type() == QEvent::KeyPress) {
QKeyEvent* ke = static_cast<QKeyEvent*>(ev);
if (ke->key() == Qt::Key_Return || ke->key() == Qt::Key_Enter) {
openNumPad();
return true;
}
// 旋钮档:↑ 加一档、↓ 减一档(每档 = m_step)。Tab/Shift+Tab 走焦点链、
// 空格激活按钮,各不重叠;按住方向键由按键自动重复继续调
if (ke->key() == Qt::Key_Up) {
adjustByKnob(1);
return true;
}
if (ke->key() == Qt::Key_Down) {
adjustByKnob(-1);
return true;
}
}
}
return QWidget::eventFilter(obj, ev);
}
void ParamControl::openNumPad()
{
NumPadDialog dlg(window()); // 以顶层窗口为父:遮罩覆盖整屏
dlg.setParamMode(true); // 参数模式:回显显示实际数字,“清除”换成“小数点”
dlg.setCompact(true); // 紧凑尺寸(不影响密码页的大键盘)
dlg.setAnchorWidget(m_valueEdit, 20); // 面板贴在输入框左侧 20px 处弹出
dlg.setMaxLen(6);
dlg.setValue(m_step < 1.0 ? QString::number(m_value, 'f', 1)
: QString::number(m_value, 'f', 0));
if (dlg.exec() != QDialog::Accepted)
return;
bool ok = false;
const double v = dlg.value().toDouble(&ok);
if (!ok)
return;
const double old = m_value;
setValue(v);
if (m_value != old)
emit valueChanged(m_value);
}
void ParamControl::refresh()
{
// 框内只显示数值(单位在框后面的标签里)
if (m_step < 1.0)
m_valueEdit->setText(QString::number(m_value, 'f', 1));
else
m_valueEdit->setText(QString::number(m_value, 'f', 0));
}