Files
VX5_KRO_GearPump/DigitalInput.cpp
T

226 lines
7.5 KiB
C++

#include "DigitalInput.h"
#include "ui_digitalinput.h"
#include "MyInputMethod.h"
#include <QObject>
#include <QSpinBox>
#include <QDoubleSpinBox>
#include <QSpinBox>
#include <QRegularExpression>
#include <QDebug>
#include <QKeyEvent>
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<QPushButton*> btns = findChildren<QPushButton*>();
for (QPushButton* btn : btns) {
btn->setFocusPolicy(Qt::NoFocus);
}
ui->traceEdit->setFocusPolicy(Qt::StrongFocus);
}
DigitalInput::~DigitalInput()
{
delete ui;
}
void DigitalInput::onCharPressed(){
QPushButton * button = qobject_cast<QPushButton *>(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<QDoubleSpinBox*>(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<QSpinBox*>(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<const QString&>::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();
}
}