#include "DigitalInput.h" #include "ui_digitalinput.h" #include "MyInputMethod.h" #include #include #include #include #include #include #include DigitalInput::DigitalInput(MyInputMethod *myInputMethod,QWidget *parent) : QWidget(parent,(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::Tool | Qt::BypassWindowManagerHint)), ui(new Ui::DigitalInput) { ui->setupUi(this); this->myInputMethod = myInputMethod; connect(ui->Key_0,SIGNAL(pressed()),this,SLOT(onCharPressed())); connect(ui->Key_1,SIGNAL(pressed()),this,SLOT(onCharPressed())); connect(ui->Key_2,SIGNAL(pressed()),this,SLOT(onCharPressed())); connect(ui->Key_3,SIGNAL(pressed()),this,SLOT(onCharPressed())); connect(ui->Key_4,SIGNAL(pressed()),this,SLOT(onCharPressed())); connect(ui->Key_5,SIGNAL(pressed()),this,SLOT(onCharPressed())); connect(ui->Key_6,SIGNAL(pressed()),this,SLOT(onCharPressed())); connect(ui->Key_7,SIGNAL(pressed()),this,SLOT(onCharPressed())); connect(ui->Key_8,SIGNAL(pressed()),this,SLOT(onCharPressed())); connect(ui->Key_9,SIGNAL(pressed()),this,SLOT(onCharPressed())); connect(ui->Key_pluse,SIGNAL(pressed()),this,SLOT(onCharPressed())); connect(ui->Key_dot, SIGNAL(pressed()),this,SLOT(onCharPressed())); connect(ui->Key_backspace,SIGNAL(pressed()),this,SLOT(onKeyBackspacePressed())); // connect(ui->Key_selectAll,SIGNAL(pressed()),this,SLOT(onKeySelectAllPressed())); // connect(ui->Key_up,SIGNAL(pressed()),this,SLOT(onKeyUpPressed())); // connect(ui->Key_down,SIGNAL(pressed()),this,SLOT(onKeyDownPressed())); connect(ui->enterBtn, &QPushButton::clicked, this, &DigitalInput::onEnterPressed); connect(ui->clrBtn, &QPushButton::clicked, this, &DigitalInput::onClrPressed); // 所有键盘按钮不接收焦点,避免点击按钮时 traceEdit 丢失焦点 QList btns = findChildren(); for (QPushButton* btn : btns) { btn->setFocusPolicy(Qt::NoFocus); } ui->traceEdit->setFocusPolicy(Qt::StrongFocus); } DigitalInput::~DigitalInput() { delete ui; } void DigitalInput::onCharPressed(){ QPushButton * button = qobject_cast(sender()); QString ch = button->text(); if (!m_currSpinBox && !m_currDoubleSpinBox) { ui->traceEdit->insert(ch); return; } int cursorPos = ui->traceEdit->cursorPosition(); QString currentText = ui->traceEdit->text(); QString newText = currentText.left(cursorPos) + ch + currentText.mid(cursorPos); if (newText.isEmpty()) { ui->traceEdit->insert(ch); return; } if(m_currDoubleSpinBox) { // 用正则表达式判定 newText是否是一个浮点数或部分浮点输入。 // 允许的示例: 0.2251, 15.335, 15, -924.02, 5. (末尾点为临时状态), .5 // 也允许单独的正负号作为正在输入中的状态: "-" 或 "+" QString simulated = newText; // Allow single sign while typing if (simulated == "-" || simulated == "+") { ui->traceEdit->insert(ch); return; } // Regular expression: optional sign, then either digits with optional dot+digits, or dot+digits, or digits+dot (partial) // 不限制小数位数;最终的最小/最大以及精度由 hideEvent 写回时决定 QRegularExpression re("^[+-]?((\\d+(\\.\\d*)?)|(\\.\\d*))$"); QRegularExpressionMatch match = re.match(simulated); if (!match.hasMatch()) { // not a valid float format (even partial) -> reject return; } // acceptable -> insert ui->traceEdit->insert(ch); return; } if(ch == "." && m_currSpinBox) { // SpinBox不能输入 . return; } if(ch == "-" && m_currSpinBox->minimum() < 0 && currentText.isEmpty()) { ui->traceEdit->insert(ch); return; } bool ok = false; int value = newText.toInt(&ok); if (!ok) { return; } int max = m_currSpinBox->maximum(); if (value <= max) { ui->traceEdit->insert(ch); } } void DigitalInput::onKeyBackspacePressed(){ int cursorPos = ui->traceEdit->cursorPosition(); if (cursorPos > 0) { QString text = ui->traceEdit->text(); text.remove(cursorPos - 1, 1); ui->traceEdit->setText(text); ui->traceEdit->setCursorPosition(cursorPos - 1); } } void DigitalInput::onKeySelectAllPressed(){ #ifndef Q_OS_WIN32 //QWSServer::sendKeyEvent(0,Qt::Key_A,Qt::ControlModifier,true,false); //锟斤拷系统锟斤拷锟酵硷拷锟斤拷锟铰硷拷 //if(!init) // QWSServer::sendKeyEvent(0,Qt::Key_A,Qt::ControlModifier,true,false); //锟斤拷系统锟斤拷锟酵硷拷锟斤拷锟铰硷拷 //init = 1; MyInputMethod::sendEvent(Qt::Key_A, Qt::ControlModifier); #endif } void DigitalInput::onKeyUpPressed(){ #ifndef Q_OS_WIN32 //QWSServer::sendKeyEvent(0,Qt::Key_Up,Qt::NoModifier,true,false); //锟斤拷系统锟斤拷锟酵硷拷锟斤拷锟铰硷拷 MyInputMethod::sendEvent(Qt::Key_Up,Qt::NoModifier); #endif } void DigitalInput::onKeyDownPressed(){ #ifndef Q_OS_WIN32 //QWSServer::sendKeyEvent(0,Qt::Key_Down,Qt::NoModifier,true,false); //锟斤拷系统锟斤拷锟酵硷拷锟斤拷锟铰硷拷 MyInputMethod::sendEvent(Qt::Key_Down,Qt::NoModifier); #endif } void DigitalInput::onEnterPressed() { hide(); } void DigitalInput::onClrPressed() { ui->traceEdit->clear(); ui->traceEdit->setFocus(); } void DigitalInput::showEvent(QShowEvent *event) { QWidget::showEvent(event); raise(); auto focusWidget = qApp->focusWidget(); QDoubleSpinBox* dbox = dynamic_cast(focusWidget); if (dbox) { m_currDoubleSpinBox = dbox; m_currSpinBox = nullptr; // Show value without padding trailing zeros (avoid decimals() padding) ui->traceEdit->setText(QString::number(dbox->value(), 'g', 15)); ui->traceEdit->setFocus(); qDebug() << "The traceEdit has connected to the QDoubleSpinBox: " << dbox->objectName(); return; } QSpinBox* box = dynamic_cast(focusWidget); if(!box) { qWarning() << "focusWidget is not QSpinBox or QDoubleSpinBox"; m_currSpinBox = nullptr; m_currDoubleSpinBox = nullptr; return; } m_currSpinBox = box; m_currDoubleSpinBox = nullptr; ui->traceEdit->setText(box->text()); // focusWidget->clearFocus(); ui->traceEdit->setFocus(); // connect(box, QOverload::of(&QSpinBox::valueChanged), ui->traceEdit, &QLineEdit::setText); qDebug() << "The traceEdit has connected to the QSpinBox: " << box->objectName(); } void DigitalInput::hideEvent(QHideEvent * event) { QWidget::hideEvent(event); if (m_currDoubleSpinBox) { bool ok = false; double value = ui->traceEdit->text().toDouble(&ok); if (!ok) value = m_currDoubleSpinBox->value(); double min = m_currDoubleSpinBox->minimum(); double max = m_currDoubleSpinBox->maximum(); value = qBound(min, value, max); m_currDoubleSpinBox->setValue(value); m_currDoubleSpinBox->clearFocus(); return; } if(m_currSpinBox) { int value = ui->traceEdit->text().toInt(); int min = m_currSpinBox->minimum(); int max = m_currSpinBox->maximum(); value = qBound(min, value, max); m_currSpinBox->setValue(value); m_currSpinBox->clearFocus(); } }