增加通讯协议
This commit is contained in:
+142
-61
@@ -18,101 +18,81 @@ NumPadDialog::NumPadDialog(QWidget* parent)
|
||||
if (parent) setGeometry(parent->rect());
|
||||
setStyleSheet("background-color: rgba(0,0,0,102);");
|
||||
|
||||
// 面板(居中)
|
||||
QWidget* panel = new QWidget(this);
|
||||
panel->setObjectName("NumPadPanel");
|
||||
panel->setFixedSize(600, 730);
|
||||
panel->setStyleSheet(QString(
|
||||
// 面板(默认居中,可用 setAnchorWidget 定位到某个控件旁边)
|
||||
m_panel = new QWidget(this);
|
||||
m_panel->setObjectName("NumPadPanel");
|
||||
m_panel->setStyleSheet(QString(
|
||||
"QWidget#NumPadPanel{background-color:%1;border:4px solid %2;border-radius:16px;}"
|
||||
"QPushButton[numpad=\"true\"]{background-color:#2D3947;color:#E6EDF3;border:1px solid #3D4A59;border-radius:12px;font-size:40px;}"
|
||||
"QPushButton[numpad=\"true\"]:pressed{background-color:#2E7BE6;color:#FFFFFF;}"
|
||||
"QPushButton[numpad=\"true\"]:focus{background-color:#3D8BFD;color:#FFFFFF;border:2px solid #8ABFFF;}")
|
||||
.arg(C::PANEL, C::BORDER));
|
||||
|
||||
QVBoxLayout* panelLay = new QVBoxLayout(panel);
|
||||
panelLay->setContentsMargins(24, 40, 24, 50);
|
||||
panelLay->setSpacing(50);
|
||||
m_panelLay = new QVBoxLayout(m_panel);
|
||||
|
||||
// 输入回显
|
||||
m_echo = new QLineEdit(panel);
|
||||
m_echo = new QLineEdit(m_panel);
|
||||
m_echo->setReadOnly(true);
|
||||
m_echo->setEchoMode(QLineEdit::Password);
|
||||
m_echo->setAlignment(Qt::AlignCenter);
|
||||
m_echo->setFixedSize(510, 100);
|
||||
m_echo->setStyleSheet("font-size:70px;");
|
||||
m_echo->setFocusPolicy(Qt::NoFocus); // 纯显示回显:不参与 Tab 选中
|
||||
m_echo->setFocusPolicy(Qt::NoFocus); // 纯显示回显:不参与 Tab 选中
|
||||
m_echo->setAttribute(Qt::WA_TransparentForMouseEvents); // 且点击穿透,不响应鼠标
|
||||
panelLay->addWidget(m_echo, 0, Qt::AlignHCenter);
|
||||
m_panelLay->addWidget(m_echo, 0, Qt::AlignHCenter);
|
||||
|
||||
// 数字键区(1-9, 0, 退格, 清除)
|
||||
QGridLayout* grid = new QGridLayout();
|
||||
grid->setSpacing(30);
|
||||
// 数字键区(1-9, 0, 退格, 清除/小数点)
|
||||
m_grid = new QGridLayout();
|
||||
const QString digits[3][3] = {{"1","2","3"},{"4","5","6"},{"7","8","9"}};
|
||||
for (int r = 0; r < 3; ++r)
|
||||
for (int c = 0; c < 3; ++c) {
|
||||
QPushButton* b = new QPushButton(digits[r][c], panel);
|
||||
QPushButton* b = new QPushButton(digits[r][c], m_panel);
|
||||
b->setProperty("numpad", true);
|
||||
b->setStyleSheet("font-size:50px;");
|
||||
b->setFixedSize(150, 120);
|
||||
connect(b, &QPushButton::clicked, this, [this, d = digits[r][c]](){ onDigit(d); });
|
||||
grid->addWidget(b, r, c);
|
||||
m_grid->addWidget(b, r, c);
|
||||
m_digits << b;
|
||||
}
|
||||
|
||||
QPushButton* b0 = new QPushButton("0", panel);
|
||||
QPushButton* b0 = new QPushButton("0", m_panel);
|
||||
b0->setProperty("numpad", true);
|
||||
b0->setStyleSheet("font-size:50px;");
|
||||
b0->setFixedSize(150, 120);
|
||||
connect(b0, &QPushButton::clicked, this, [this](){ onDigit("0"); });
|
||||
grid->addWidget(b0, 3, 1);
|
||||
m_grid->addWidget(b0, 3, 1);
|
||||
m_digits << b0;
|
||||
|
||||
QPushButton* bBack = new QPushButton("退格", panel);
|
||||
bBack->setProperty("numpad", true);
|
||||
bBack->setStyleSheet("font-size:40px;");
|
||||
bBack->setFixedSize(150, 120);
|
||||
connect(bBack, &QPushButton::clicked, this, &NumPadDialog::onBackspace);
|
||||
grid->addWidget(bBack, 3, 0);
|
||||
m_backKey = new QPushButton("退格", m_panel);
|
||||
m_backKey->setProperty("numpad", true);
|
||||
connect(m_backKey, &QPushButton::clicked, this, &NumPadDialog::onBackspace);
|
||||
m_grid->addWidget(m_backKey, 3, 0);
|
||||
|
||||
QPushButton* bClear = new QPushButton("清除", panel);
|
||||
bClear->setProperty("numpad", true);
|
||||
bClear->setStyleSheet("font-size:40px;");
|
||||
bClear->setFixedSize(150, 108);
|
||||
connect(bClear, &QPushButton::clicked, this, &NumPadDialog::onClear);
|
||||
grid->addWidget(bClear, 3, 2);
|
||||
m_clearKey = new QPushButton("清除", m_panel);
|
||||
m_clearKey->setProperty("numpad", true);
|
||||
connect(m_clearKey, &QPushButton::clicked, this, [this]() {
|
||||
if (m_paramMode) onDot();
|
||||
else onClear();
|
||||
});
|
||||
m_grid->addWidget(m_clearKey, 3, 2);
|
||||
|
||||
// 确认 / 取消(与数字键一致的灰底,选中时发亮)
|
||||
QPushButton* bOk = new QPushButton("确认", panel);
|
||||
bOk->setProperty("numpad", true);
|
||||
bOk->setStyleSheet("font-size:60px;");
|
||||
bOk->setFixedSize(160, 140);
|
||||
connect(bOk, &QPushButton::clicked, this, &NumPadDialog::accept);
|
||||
// 确认 / 取消
|
||||
m_okKey = new QPushButton("确认", m_panel);
|
||||
m_okKey->setProperty("numpad", true);
|
||||
connect(m_okKey, &QPushButton::clicked, this, &NumPadDialog::accept);
|
||||
|
||||
QPushButton* bCancel = new QPushButton("取消", panel);
|
||||
bCancel->setProperty("numpad", true);
|
||||
bCancel->setStyleSheet(cancelButtonStyle(60)); // 选中时红底白字
|
||||
bCancel->setFixedSize(160, 140);
|
||||
connect(bCancel, &QPushButton::clicked, this, &NumPadDialog::reject);
|
||||
m_cancelKey = new QPushButton("取消", m_panel);
|
||||
m_cancelKey->setProperty("numpad", true);
|
||||
connect(m_cancelKey, &QPushButton::clicked, this, &NumPadDialog::reject);
|
||||
|
||||
// 确认 / 取消:单独一行、水平居中,并与数字键盘留出间隔
|
||||
QHBoxLayout* okRow = new QHBoxLayout();
|
||||
okRow->setSpacing(80);
|
||||
okRow->addStretch(1);
|
||||
okRow->addWidget(bOk);
|
||||
okRow->addWidget(bCancel);
|
||||
okRow->addWidget(m_okKey);
|
||||
okRow->addWidget(m_cancelKey);
|
||||
okRow->addStretch(1);
|
||||
|
||||
panelLay->addLayout(grid);
|
||||
panelLay->setAlignment(grid, Qt::AlignHCenter);
|
||||
//panelLay->addSpacing(20);
|
||||
panelLay->addLayout(okRow);
|
||||
panelLay->addStretch(1);
|
||||
|
||||
// 居中放置面板
|
||||
QVBoxLayout* root = new QVBoxLayout(this);
|
||||
root->setContentsMargins(0, 0, 0, 0);
|
||||
root->addStretch(1);
|
||||
root->addWidget(panel, 0, Qt::AlignHCenter);
|
||||
root->addStretch(1);
|
||||
m_panelLay->addLayout(m_grid);
|
||||
m_panelLay->setAlignment(m_grid, Qt::AlignHCenter);
|
||||
m_panelLay->addLayout(okRow);
|
||||
m_panelLay->addStretch(1);
|
||||
|
||||
applySizes(); // 应用尺寸(默认大字版)并摆放面板
|
||||
refreshEcho();
|
||||
}
|
||||
|
||||
@@ -128,6 +108,107 @@ void NumPadDialog::clear()
|
||||
refreshEcho();
|
||||
}
|
||||
|
||||
// 整体不透明度(0.0~1.0)
|
||||
void NumPadDialog::setOpacity(qreal opacity)
|
||||
{
|
||||
setWindowOpacity(opacity);
|
||||
}
|
||||
|
||||
// 面板贴在参照控件左侧 gap 像素处弹出(垂直对齐其中心,并钳位到屏幕内)
|
||||
void NumPadDialog::setAnchorWidget(QWidget* ref, int gap)
|
||||
{
|
||||
m_anchor = ref;
|
||||
m_gap = gap;
|
||||
placePanel();
|
||||
}
|
||||
|
||||
// 参数输入模式:回显显示实际数字(不掩码),“清除”键换成“小数点”
|
||||
void NumPadDialog::setParamMode(bool on)
|
||||
{
|
||||
m_paramMode = on;
|
||||
m_echo->setEchoMode(on ? QLineEdit::Normal : QLineEdit::Password);
|
||||
m_clearKey->setText(on ? "." : "清除");
|
||||
applySizes(); // 重设“小数点/清除”键的字号
|
||||
}
|
||||
|
||||
// 紧凑尺寸(按键与面板更小),默认 false = 大字版
|
||||
void NumPadDialog::setCompact(bool on)
|
||||
{
|
||||
m_compact = on;
|
||||
applySizes();
|
||||
}
|
||||
|
||||
// 按当前尺寸模式设置面板/按键的大小与字号,并重新摆放面板
|
||||
void NumPadDialog::applySizes()
|
||||
{
|
||||
const int digitFont = m_compact ? 40 : 50;
|
||||
const int fnFont = m_compact ? 30 : 40;
|
||||
const int dotFont = m_compact ? 46 : 60;
|
||||
const int okFont = m_compact ? 44 : 60;
|
||||
const QSize digitSz = m_compact ? QSize(120, 70) : QSize(150, 120);
|
||||
const QSize clearSz = m_compact ? QSize(120, 70) : QSize(150, 108);
|
||||
const QSize okSz = m_compact ? QSize(130, 88) : QSize(160, 140);
|
||||
|
||||
m_panel->setFixedSize(m_compact ? QSize(460, 600) : QSize(600, 730));
|
||||
m_panelLay->setContentsMargins(m_compact ? 20 : 24, m_compact ? 24 : 40,
|
||||
m_compact ? 20 : 24, m_compact ? 26 : 50);
|
||||
m_panelLay->setSpacing(m_compact ? 26 : 50);
|
||||
m_grid->setSpacing(m_compact ? 18 : 30);
|
||||
|
||||
m_echo->setFixedSize(m_compact ? QSize(400, 70) : QSize(510, 100));
|
||||
m_echo->setStyleSheet(QString("font-size:%1px;").arg(m_compact ? 48 : 70));
|
||||
|
||||
for (QPushButton* b : m_digits) {
|
||||
b->setFixedSize(digitSz);
|
||||
b->setStyleSheet(QString("font-size:%1px;").arg(digitFont));
|
||||
}
|
||||
m_backKey->setFixedSize(digitSz);
|
||||
m_backKey->setStyleSheet(QString("font-size:%1px;").arg(fnFont));
|
||||
|
||||
m_clearKey->setFixedSize(clearSz);
|
||||
m_clearKey->setStyleSheet(QString("font-size:%1px;").arg(m_paramMode ? dotFont : fnFont));
|
||||
|
||||
m_okKey->setFixedSize(okSz);
|
||||
m_okKey->setStyleSheet(QString("font-size:%1px;").arg(okFont));
|
||||
m_cancelKey->setFixedSize(okSz);
|
||||
m_cancelKey->setStyleSheet(cancelButtonStyle(okFont)); // 选中时红底白字
|
||||
|
||||
placePanel();
|
||||
}
|
||||
|
||||
// 计算面板位置:有参照控件 → 其左侧;否则居中
|
||||
void NumPadDialog::placePanel()
|
||||
{
|
||||
const int w = m_panel->width();
|
||||
const int h = m_panel->height();
|
||||
int x = (width() - w) / 2;
|
||||
int y = (height() - h) / 2;
|
||||
|
||||
if (m_anchor && m_anchor->window()) {
|
||||
// 面板放在参照控件左侧;对话框覆盖整个窗口,其局部坐标即窗口坐标
|
||||
const QPoint p = m_anchor->mapTo(m_anchor->window(), QPoint(0, 0));
|
||||
x = p.x() - m_gap - w;
|
||||
y = p.y() + m_anchor->height() / 2 - h / 2;
|
||||
}
|
||||
|
||||
x = qBound(0, x, qMax(0, width() - w));
|
||||
y = qBound(0, y, qMax(0, height() - h));
|
||||
m_panel->move(x, y);
|
||||
}
|
||||
|
||||
// 小数点:仅允许一个,空值时补前导 0
|
||||
void NumPadDialog::onDot()
|
||||
{
|
||||
if (m_value.contains('.'))
|
||||
return;
|
||||
if (m_value.isEmpty())
|
||||
m_value = "0";
|
||||
if (m_value.size() >= m_maxLen)
|
||||
return;
|
||||
m_value += '.';
|
||||
refreshEcho();
|
||||
}
|
||||
|
||||
void NumPadDialog::onDigit(const QString& d)
|
||||
{
|
||||
if (m_value.size() >= m_maxLen)
|
||||
|
||||
Reference in New Issue
Block a user