5 changed files with 203 additions and 241 deletions
@ -1,7 +1,11 @@ |
|||||
INCLUDEPATH += $$PWD/ |
INCLUDEPATH += $$PWD/ |
||||
|
|
||||
|
DEFINES += NUMKEYBOARD_STATIC |
||||
|
|
||||
HEADERS += $$PWD/numkeydia.h |
HEADERS += $$PWD/numkeydia.h |
||||
|
|
||||
SOURCES += $$PWD/numkeydia.cpp |
SOURCES += $$PWD/numkeydia.cpp |
||||
|
|
||||
FORMS += $$PWD/numkeydia.ui |
FORMS += $$PWD/numkeydia.ui |
||||
|
|
||||
|
RESOURCES += $$PWD/NumKeyBoard.qrc |
||||
|
|||||
@ -1,263 +1,240 @@ |
|||||
#include "numkeydia.h" |
#include "numkeydia.h" |
||||
#include "ui_numkeydia.h" |
#include "ui_numkeydia.h" |
||||
|
|
||||
#include <QDebug> |
#include <QDebug> |
||||
#include <QFile> |
#include <QFile> |
||||
#include <QMouseEvent> |
#include <QMouseEvent> |
||||
#include <QPushButton> |
#include <QPushButton> |
||||
#include <QShortcut> |
#include <QShortcut> |
||||
#include <QTextStream> |
#include <QTextStream> |
||||
#include <QtGlobal> |
|
||||
|
|
||||
namespace |
// --- 私有类定义 ---
|
||||
{ |
class NumKeyDiaPrivate { |
||||
void loadKeyboardStyleSheet(QWidget *widget) |
Q_DECLARE_PUBLIC(NumKeyDia) |
||||
{ |
|
||||
if(!widget) |
|
||||
{ |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
QFile file(QStringLiteral(":/commonWidget.qss")); |
public: |
||||
if(!file.open(QFile::ReadOnly | QFile::Text)) |
NumKeyDiaPrivate(NumKeyDia *q) : q_ptr(q) {} |
||||
{ |
|
||||
qDebug() << QStringLiteral("Unable to load keyboard stylesheet"); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
QTextStream stream(&file); |
// 成员变量移入 D-pointer
|
||||
widget->setStyleSheet(stream.readAll()); |
Ui::NumKeyDia *ui = nullptr; |
||||
} |
QString value; |
||||
} |
QPoint m_point; |
||||
|
bool m_firstInputFlag = true; |
||||
|
|
||||
NumKeyDia *NumKeyDia::singleton = nullptr; |
enum class InputPage { NumberPage, SymbolPage }; |
||||
|
InputPage m_inputPage = InputPage::NumberPage; |
||||
NumKeyDia::NumKeyDia(QWidget *parent) : |
|
||||
QDialog(parent), |
|
||||
ui(new Ui::NumKeyDia) |
|
||||
{ |
|
||||
loadKeyboardStyleSheet(this); |
|
||||
if(singleton != nullptr) |
|
||||
{ |
|
||||
return; |
|
||||
} |
|
||||
singleton = this; |
|
||||
ui->setupUi(this); |
|
||||
this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); |
|
||||
ui->lineEdit_input->setFocusPolicy(Qt::StrongFocus); |
|
||||
auto _btnInputList = ui->widget_input->findChildren<QPushButton *>(); |
|
||||
foreach (auto &i, _btnInputList) |
|
||||
{ |
|
||||
connect(i, &QPushButton::clicked, this, &NumKeyDia::btn_input_clicked); |
|
||||
i->setFocusPolicy(Qt::NoFocus); |
|
||||
} |
|
||||
|
|
||||
auto *returnShortcut = new QShortcut(QKeySequence(Qt::Key_Return), this); |
// 辅助函数
|
||||
connect(returnShortcut, &QShortcut::activated, this, &NumKeyDia::on_btn_ok_clicked); |
void setInputPage(InputPage page); |
||||
|
void refreshInputButtons(); |
||||
|
void configureInputButton(QPushButton *button, const QString &label, |
||||
|
const QString &value, bool enabled, bool isModeSwitch = false); |
||||
|
void loadStyleSheet(); |
||||
|
|
||||
auto *enterShortcut = new QShortcut(QKeySequence(Qt::Key_Enter), this); |
private: |
||||
connect(enterShortcut, &QShortcut::activated, this, &NumKeyDia::on_btn_ok_clicked); |
NumKeyDia *q_ptr; // 反向指针
|
||||
|
}; |
||||
|
|
||||
ui->toolButton_ico->installEventFilter(this); |
// --- 私有类逻辑实现 ---
|
||||
ui->label_appInfo->installEventFilter(this); |
|
||||
ui->btn_clear->setText(QStringLiteral("<")); |
|
||||
setInputPage(InputPage::NumberPage); |
|
||||
} |
|
||||
|
|
||||
NumKeyDia::~NumKeyDia() |
void NumKeyDiaPrivate::loadStyleSheet() { |
||||
{ |
QFile file(QStringLiteral(":/commonWidget.qss")); |
||||
if(singleton == this) |
if (file.open(QFile::ReadOnly | QFile::Text)) { |
||||
{ |
QTextStream stream(&file); |
||||
singleton = nullptr; |
q_ptr->setStyleSheet(stream.readAll()); |
||||
} |
} |
||||
delete ui; |
|
||||
} |
} |
||||
|
|
||||
bool NumKeyDia::eventFilter(QObject *, QEvent *event) |
void NumKeyDiaPrivate::setInputPage(InputPage page) { |
||||
{ |
m_inputPage = page; |
||||
if(event->type() == QEvent::MouseButtonPress) |
refreshInputButtons(); |
||||
{ |
|
||||
auto *mouseEvent = static_cast<QMouseEvent *>(event); |
|
||||
m_point = mouseEvent->globalPos() - frameGeometry().topLeft(); |
|
||||
} |
|
||||
else if(event->type() == QEvent::MouseMove) |
|
||||
{ |
|
||||
auto *mouseEvent = static_cast<QMouseEvent *>(event); |
|
||||
move(mouseEvent->globalPos() - m_point); |
|
||||
} |
} |
||||
return false; |
|
||||
|
void NumKeyDiaPrivate::refreshInputButtons() { |
||||
|
if (m_inputPage == InputPage::NumberPage) { |
||||
|
configureInputButton(ui->btn_1, "1", "1", true); |
||||
|
configureInputButton(ui->btn_2, "2", "2", true); |
||||
|
configureInputButton(ui->btn_3, "3", "3", true); |
||||
|
configureInputButton(ui->btn_4, "4", "4", true); |
||||
|
configureInputButton(ui->btn_5, "5", "5", true); |
||||
|
configureInputButton(ui->btn_6, "6", "6", true); |
||||
|
configureInputButton(ui->btn_7, "7", "7", true); |
||||
|
configureInputButton(ui->btn_8, "8", "8", true); |
||||
|
configureInputButton(ui->btn_9, "9", "9", true); |
||||
|
configureInputButton(ui->btn_sub, "#+=", "", true, true); |
||||
|
configureInputButton(ui->btn_0, "0", "0", true); |
||||
|
configureInputButton(ui->pushButton_dot, ".", ".", true); |
||||
|
} else { |
||||
|
configureInputButton(ui->btn_1, "/", "/", true); |
||||
|
configureInputButton(ui->btn_2, "-", "-", true); |
||||
|
configureInputButton(ui->btn_3, ":", ":", true); |
||||
|
QString deg = QChar(0x00B0); |
||||
|
configureInputButton(ui->btn_4, deg, deg, true); |
||||
|
configureInputButton(ui->btn_5, "'", "'", true); |
||||
|
configureInputButton(ui->btn_6, "\"", "\"", true); |
||||
|
configureInputButton(ui->btn_7, ".", ".", true); |
||||
|
configureInputButton(ui->btn_8, "_", "_", true); |
||||
|
configureInputButton(ui->btn_9, "@", "@", true); |
||||
|
configureInputButton(ui->btn_sub, "123", "", true, true); |
||||
|
configureInputButton(ui->btn_0, "+", "+", true); |
||||
|
configureInputButton(ui->pushButton_dot, ",", ",", true); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void NumKeyDiaPrivate::configureInputButton(QPushButton *button, const QString &label, |
||||
|
const QString &value, bool enabled, bool isModeSwitch) { |
||||
|
if (!button) return; |
||||
|
button->setText(label); |
||||
|
button->setEnabled(enabled); |
||||
|
button->setProperty("inputValue", value); |
||||
|
button->setProperty("isModeSwitch", isModeSwitch); |
||||
} |
} |
||||
|
|
||||
void NumKeyDia::setValue(const QString &value) |
// --- 公共类实现 ---
|
||||
{ |
|
||||
this->value = value; |
|
||||
setInputPage(InputPage::NumberPage); |
|
||||
ui->lineEdit_input->setFocus(); |
|
||||
ui->lineEdit_input->setText(value); |
|
||||
ui->lineEdit_input->setCursorPosition(ui->lineEdit_input->text().size()); |
|
||||
|
|
||||
m_firstInputFlag = true; |
NumKeyDia *NumKeyDia::singleton = nullptr; |
||||
} |
|
||||
|
|
||||
QString &NumKeyDia::getValue() |
NumKeyDia::NumKeyDia(QWidget *parent) |
||||
|
: QDialog(parent) |
||||
|
, d_ptr(new NumKeyDiaPrivate(this)) // 初始化 d_ptr
|
||||
{ |
{ |
||||
return value; |
Q_D(NumKeyDia); |
||||
} |
|
||||
|
|
||||
void NumKeyDia::on_btn_ok_clicked() |
if (!singleton) singleton = this; |
||||
{ |
|
||||
QString _res = ui->lineEdit_input->text(); |
|
||||
if(_res.isEmpty()) |
|
||||
{ |
|
||||
_res = QStringLiteral("0"); |
|
||||
} |
|
||||
|
|
||||
value = _res; |
Q_INIT_RESOURCE(NumKeyBoard); |
||||
|
|
||||
closeKeyBoard(); |
d->ui = new Ui::NumKeyDia; |
||||
} |
d->ui->setupUi(this); |
||||
|
d->loadStyleSheet(); |
||||
|
|
||||
void NumKeyDia::on_btn_cancel_clicked() |
setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); |
||||
{ |
d->ui->lineEdit_input->setFocusPolicy(Qt::StrongFocus); |
||||
closeKeyBoard(); |
|
||||
} |
|
||||
|
|
||||
void NumKeyDia::on_btn_clear_clicked() |
auto btnList = d->ui->widget_input->findChildren<QPushButton *>(); |
||||
{ |
for (auto *btn : btnList) { |
||||
m_firstInputFlag = false; |
connect(btn, &QPushButton::clicked, this, &NumKeyDia::btn_input_clicked); |
||||
const int currentPosition = ui->lineEdit_input->cursorPosition(); |
btn->setFocusPolicy(Qt::NoFocus); |
||||
ui->lineEdit_input->setCursorPosition(qMax(0, currentPosition - 1)); |
|
||||
ui->lineEdit_input->setFocus(); |
|
||||
} |
} |
||||
|
|
||||
void NumKeyDia::on_btn_back_clicked() |
auto *okShortcut = new QShortcut(QKeySequence(Qt::Key_Return), this); |
||||
{ |
connect(okShortcut, &QShortcut::activated, this, &NumKeyDia::on_btn_ok_clicked); |
||||
m_firstInputFlag = false; |
|
||||
|
|
||||
int _index = ui->lineEdit_input->cursorPosition(); |
d->ui->toolButton_ico->installEventFilter(this); |
||||
QString _currentText = ui->lineEdit_input->text(); |
d->ui->label_appInfo->installEventFilter(this); |
||||
|
d->ui->btn_clear->setText(QStringLiteral("<")); |
||||
|
|
||||
if(_currentText.isEmpty()) |
d->setInputPage(NumKeyDiaPrivate::InputPage::NumberPage); |
||||
{ |
|
||||
ui->lineEdit_input->setFocus(); |
|
||||
} |
} |
||||
|
|
||||
if(_index != 0) |
NumKeyDia::~NumKeyDia() { |
||||
{ |
if (singleton == this) singleton = nullptr; |
||||
_currentText.remove(_index - 1, 1); |
// QScopedPointer 会自动删除 d_ptr,但 Ui 需手动销毁(如果没设置 parent)
|
||||
ui->lineEdit_input->setText(_currentText); |
Q_D(NumKeyDia); |
||||
|
delete d->ui; |
||||
} |
} |
||||
|
|
||||
ui->lineEdit_input->setFocus(); |
NumKeyDia* NumKeyDia::instance() { |
||||
ui->lineEdit_input->setCursorPosition(qMax(0, _index - 1)); |
if(!singleton) |
||||
|
singleton = new NumKeyDia; |
||||
|
return singleton; |
||||
} |
} |
||||
|
|
||||
void NumKeyDia::btn_input_clicked() |
bool NumKeyDia::eventFilter(QObject *, QEvent *event) { |
||||
{ |
Q_D(NumKeyDia); |
||||
auto *_btnClicked = qobject_cast<QPushButton *>(sender()); |
if (event->type() == QEvent::MouseButtonPress) { |
||||
if(!_btnClicked) |
auto *mouseEvent = static_cast<QMouseEvent *>(event); |
||||
{ |
d->m_point = mouseEvent->globalPos() - frameGeometry().topLeft(); |
||||
return; |
} else if (event->type() == QEvent::MouseMove) { |
||||
|
auto *mouseEvent = static_cast<QMouseEvent *>(event); |
||||
|
move(mouseEvent->globalPos() - d->m_point); |
||||
} |
} |
||||
|
return false; |
||||
if(_btnClicked->property("isModeSwitch").toBool()) |
|
||||
{ |
|
||||
const auto nextPage = (m_inputPage == InputPage::NumberPage) |
|
||||
? InputPage::SymbolPage |
|
||||
: InputPage::NumberPage; |
|
||||
setInputPage(nextPage); |
|
||||
ui->lineEdit_input->setFocus(); |
|
||||
return; |
|
||||
} |
} |
||||
|
|
||||
if(m_firstInputFlag) |
void NumKeyDia::setValue(const QString &value) { |
||||
{ |
Q_D(NumKeyDia); |
||||
ui->lineEdit_input->clear(); |
d->value = value; |
||||
m_firstInputFlag = false; |
d->setInputPage(NumKeyDiaPrivate::InputPage::NumberPage); |
||||
|
d->ui->lineEdit_input->setFocus(); |
||||
|
d->ui->lineEdit_input->setText(value); |
||||
|
d->ui->lineEdit_input->setCursorPosition(d->ui->lineEdit_input->text().size()); |
||||
|
d->m_firstInputFlag = true; |
||||
} |
} |
||||
|
|
||||
const QString _inputValue = _btnClicked->property("inputValue").toString(); |
QString &NumKeyDia::getValue() { |
||||
if(_inputValue.isEmpty()) |
Q_D(NumKeyDia); |
||||
{ |
return d->value; |
||||
ui->lineEdit_input->setFocus(); |
|
||||
return; |
|
||||
} |
} |
||||
|
|
||||
int _index = ui->lineEdit_input->cursorPosition(); |
void NumKeyDia::on_btn_ok_clicked() { |
||||
QString _currentText = ui->lineEdit_input->text(); |
Q_D(NumKeyDia); |
||||
|
QString res = d->ui->lineEdit_input->text(); |
||||
|
d->value = res.isEmpty() ? "0" : res; |
||||
|
closeKeyBoard(); |
||||
|
} |
||||
|
|
||||
_currentText.insert(_index, _inputValue); |
void NumKeyDia::on_btn_cancel_clicked() { |
||||
ui->lineEdit_input->setText(_currentText); |
closeKeyBoard(); |
||||
ui->lineEdit_input->setFocus(); |
|
||||
ui->lineEdit_input->setCursorPosition(_index + _inputValue.size()); |
|
||||
} |
} |
||||
|
|
||||
void NumKeyDia::closeKeyBoard() |
void NumKeyDia::on_btn_clear_clicked() { |
||||
{ |
Q_D(NumKeyDia); |
||||
this->close(); |
d->m_firstInputFlag = false; |
||||
|
int pos = d->ui->lineEdit_input->cursorPosition(); |
||||
|
d->ui->lineEdit_input->setCursorPosition(qMax(0, pos - 1)); |
||||
|
d->ui->lineEdit_input->setFocus(); |
||||
} |
} |
||||
|
|
||||
void NumKeyDia::setInputPage(InputPage page) |
void NumKeyDia::on_btn_back_clicked() { |
||||
{ |
Q_D(NumKeyDia); |
||||
m_inputPage = page; |
d->m_firstInputFlag = false; |
||||
refreshInputButtons(); |
int index = d->ui->lineEdit_input->cursorPosition(); |
||||
|
QString text = d->ui->lineEdit_input->text(); |
||||
|
|
||||
|
if (index > 0) { |
||||
|
text.remove(index - 1, 1); |
||||
|
d->ui->lineEdit_input->setText(text); |
||||
|
d->ui->lineEdit_input->setCursorPosition(index - 1); |
||||
|
} |
||||
|
d->ui->lineEdit_input->setFocus(); |
||||
} |
} |
||||
|
|
||||
void NumKeyDia::refreshInputButtons() |
void NumKeyDia::btn_input_clicked() { |
||||
{ |
Q_D(NumKeyDia); |
||||
if(m_inputPage == InputPage::NumberPage) |
auto *btn = qobject_cast<QPushButton *>(sender()); |
||||
{ |
if (!btn) return; |
||||
configureInputButton(ui->btn_1, QStringLiteral("1"), QStringLiteral("1"), true); |
|
||||
configureInputButton(ui->btn_2, QStringLiteral("2"), QStringLiteral("2"), true); |
if (btn->property("isModeSwitch").toBool()) { |
||||
configureInputButton(ui->btn_3, QStringLiteral("3"), QStringLiteral("3"), true); |
auto nextPage = (d->m_inputPage == NumKeyDiaPrivate::InputPage::NumberPage) |
||||
configureInputButton(ui->btn_4, QStringLiteral("4"), QStringLiteral("4"), true); |
? NumKeyDiaPrivate::InputPage::SymbolPage |
||||
configureInputButton(ui->btn_5, QStringLiteral("5"), QStringLiteral("5"), true); |
: NumKeyDiaPrivate::InputPage::NumberPage; |
||||
configureInputButton(ui->btn_6, QStringLiteral("6"), QStringLiteral("6"), true); |
d->setInputPage(nextPage); |
||||
configureInputButton(ui->btn_7, QStringLiteral("7"), QStringLiteral("7"), true); |
d->ui->lineEdit_input->setFocus(); |
||||
configureInputButton(ui->btn_8, QStringLiteral("8"), QStringLiteral("8"), true); |
|
||||
configureInputButton(ui->btn_9, QStringLiteral("9"), QStringLiteral("9"), true); |
|
||||
configureInputButton(ui->btn_sub, QStringLiteral("#+="), QString(), true, true); |
|
||||
configureInputButton(ui->btn_0, QStringLiteral("0"), QStringLiteral("0"), true); |
|
||||
configureInputButton(ui->pushButton_dot, QStringLiteral("."), QStringLiteral("."), true); |
|
||||
return; |
return; |
||||
} |
} |
||||
|
|
||||
configureInputButton(ui->btn_1, QStringLiteral("/"), QStringLiteral("/"), true); |
if (d->m_firstInputFlag) { |
||||
configureInputButton(ui->btn_2, QStringLiteral("-"), QStringLiteral("-"), true); |
d->ui->lineEdit_input->clear(); |
||||
configureInputButton(ui->btn_3, QStringLiteral(":"), QStringLiteral(":"), true); |
d->m_firstInputFlag = false; |
||||
const QString degreeSymbol(QChar(0x00B0)); |
|
||||
configureInputButton(ui->btn_4, degreeSymbol, degreeSymbol, true); |
|
||||
configureInputButton(ui->btn_5, QStringLiteral("'"), QStringLiteral("'"), true); |
|
||||
configureInputButton(ui->btn_6, QStringLiteral("\""), QStringLiteral("\""), true); |
|
||||
configureInputButton(ui->btn_7, QStringLiteral("."), QStringLiteral("."), true); |
|
||||
configureInputButton(ui->btn_8, QStringLiteral("_"), QStringLiteral("_"), true); |
|
||||
configureInputButton(ui->btn_9, QStringLiteral("@"), QStringLiteral("@"), true); |
|
||||
configureInputButton(ui->btn_sub, QStringLiteral("123"), QString(), true, true); |
|
||||
configureInputButton(ui->btn_0, QStringLiteral("+"), QStringLiteral("+"), true); |
|
||||
configureInputButton(ui->pushButton_dot, QStringLiteral(","), QStringLiteral(","), true); |
|
||||
} |
} |
||||
|
|
||||
void NumKeyDia::configureInputButton(QPushButton *button, |
QString input = btn->property("inputValue").toString(); |
||||
const QString &label, |
if (input.isEmpty()) return; |
||||
const QString &value, |
|
||||
bool enabled, |
int index = d->ui->lineEdit_input->cursorPosition(); |
||||
bool isModeSwitch) |
QString text = d->ui->lineEdit_input->text(); |
||||
{ |
text.insert(index, input); |
||||
if(!button) |
d->ui->lineEdit_input->setText(text); |
||||
{ |
d->ui->lineEdit_input->setFocus(); |
||||
return; |
d->ui->lineEdit_input->setCursorPosition(index + input.size()); |
||||
} |
} |
||||
|
|
||||
button->setText(label); |
void NumKeyDia::closeKeyBoard() { |
||||
button->setEnabled(enabled); |
this->close(); |
||||
button->setProperty("inputValue", value); |
|
||||
button->setProperty("isModeSwitch", isModeSwitch); |
|
||||
} |
} |
||||
|
|
||||
namespace KeyBoard |
namespace KeyBoard { |
||||
{ |
NumKeyDia *app() { |
||||
NumKeyDia *app() |
|
||||
{ |
|
||||
return NumKeyDia::instance(); |
return NumKeyDia::instance(); |
||||
}; |
} |
||||
}; |
} |
||||
|
|||||
Loading…
Reference in new issue