diff --git a/NumKeyBoard.pri b/NumKeyBoard.pri index a784098..a5eb3bf 100644 --- a/NumKeyBoard.pri +++ b/NumKeyBoard.pri @@ -1,7 +1,11 @@ INCLUDEPATH += $$PWD/ +DEFINES += NUMKEYBOARD_STATIC + HEADERS += $$PWD/numkeydia.h SOURCES += $$PWD/numkeydia.cpp FORMS += $$PWD/numkeydia.ui + +RESOURCES += $$PWD/NumKeyBoard.qrc diff --git a/NumKeyBoard_global.h b/NumKeyBoard_global.h index f76de20..dca045e 100644 --- a/NumKeyBoard_global.h +++ b/NumKeyBoard_global.h @@ -3,10 +3,16 @@ #include -#if defined(NUMKEYBOARD_LIBRARY) -#define NUMKEYBOARD_EXPORT Q_DECL_EXPORT +// 如果定义了 NUMKEYBOARD_STATIC,则宏为空(适用于直接引入源码编译) +#if defined(NUMKEYBOARD_STATIC) +# define NUMKEYBOARD_EXPORT #else -#define NUMKEYBOARD_EXPORT Q_DECL_IMPORT +// 如果没定义 STATIC,则在“写库”和“用库”之间切换 +# if defined(NUMKEYBOARD_LIBRARY) +# define NUMKEYBOARD_EXPORT Q_DECL_EXPORT +# else +# define NUMKEYBOARD_EXPORT Q_DECL_IMPORT +# endif #endif #endif // NUMKEYBOARD_GLOBAL_H diff --git a/numkeydia.cpp b/numkeydia.cpp index e43a611..84b1c79 100644 --- a/numkeydia.cpp +++ b/numkeydia.cpp @@ -1,263 +1,240 @@ #include "numkeydia.h" #include "ui_numkeydia.h" - #include #include #include #include #include #include -#include -namespace -{ -void loadKeyboardStyleSheet(QWidget *widget) -{ - if(!widget) - { - return; - } +// --- 私有类定义 --- +class NumKeyDiaPrivate { + Q_DECLARE_PUBLIC(NumKeyDia) + +public: + NumKeyDiaPrivate(NumKeyDia *q) : q_ptr(q) {} + + // 成员变量移入 D-pointer + Ui::NumKeyDia *ui = nullptr; + QString value; + QPoint m_point; + bool m_firstInputFlag = true; + + enum class InputPage { NumberPage, SymbolPage }; + InputPage m_inputPage = InputPage::NumberPage; + + // 辅助函数 + void setInputPage(InputPage page); + void refreshInputButtons(); + void configureInputButton(QPushButton *button, const QString &label, + const QString &value, bool enabled, bool isModeSwitch = false); + void loadStyleSheet(); + +private: + NumKeyDia *q_ptr; // 反向指针 +}; +// --- 私有类逻辑实现 --- + +void NumKeyDiaPrivate::loadStyleSheet() { QFile file(QStringLiteral(":/commonWidget.qss")); - if(!file.open(QFile::ReadOnly | QFile::Text)) - { - qDebug() << QStringLiteral("Unable to load keyboard stylesheet"); - return; + if (file.open(QFile::ReadOnly | QFile::Text)) { + QTextStream stream(&file); + q_ptr->setStyleSheet(stream.readAll()); } +} - QTextStream stream(&file); - widget->setStyleSheet(stream.readAll()); +void NumKeyDiaPrivate::setInputPage(InputPage page) { + m_inputPage = page; + refreshInputButtons(); } + +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); } +// --- 公共类实现 --- + NumKeyDia *NumKeyDia::singleton = nullptr; -NumKeyDia::NumKeyDia(QWidget *parent) : - QDialog(parent), - ui(new Ui::NumKeyDia) +NumKeyDia::NumKeyDia(QWidget *parent) + : QDialog(parent) + , d_ptr(new NumKeyDiaPrivate(this)) // 初始化 d_ptr { - 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(); - foreach (auto &i, _btnInputList) - { - connect(i, &QPushButton::clicked, this, &NumKeyDia::btn_input_clicked); - i->setFocusPolicy(Qt::NoFocus); + Q_D(NumKeyDia); + + if (!singleton) singleton = this; + + Q_INIT_RESOURCE(NumKeyBoard); + + d->ui = new Ui::NumKeyDia; + d->ui->setupUi(this); + d->loadStyleSheet(); + + setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); + d->ui->lineEdit_input->setFocusPolicy(Qt::StrongFocus); + + auto btnList = d->ui->widget_input->findChildren(); + for (auto *btn : btnList) { + connect(btn, &QPushButton::clicked, this, &NumKeyDia::btn_input_clicked); + btn->setFocusPolicy(Qt::NoFocus); } - auto *returnShortcut = new QShortcut(QKeySequence(Qt::Key_Return), this); - connect(returnShortcut, &QShortcut::activated, this, &NumKeyDia::on_btn_ok_clicked); + auto *okShortcut = new QShortcut(QKeySequence(Qt::Key_Return), this); + connect(okShortcut, &QShortcut::activated, this, &NumKeyDia::on_btn_ok_clicked); - auto *enterShortcut = new QShortcut(QKeySequence(Qt::Key_Enter), this); - connect(enterShortcut, &QShortcut::activated, this, &NumKeyDia::on_btn_ok_clicked); + d->ui->toolButton_ico->installEventFilter(this); + d->ui->label_appInfo->installEventFilter(this); + d->ui->btn_clear->setText(QStringLiteral("<")); - ui->toolButton_ico->installEventFilter(this); - ui->label_appInfo->installEventFilter(this); - ui->btn_clear->setText(QStringLiteral("<")); - setInputPage(InputPage::NumberPage); + d->setInputPage(NumKeyDiaPrivate::InputPage::NumberPage); } -NumKeyDia::~NumKeyDia() -{ - if(singleton == this) - { - singleton = nullptr; - } - delete ui; +NumKeyDia::~NumKeyDia() { + if (singleton == this) singleton = nullptr; + // QScopedPointer 会自动删除 d_ptr,但 Ui 需手动销毁(如果没设置 parent) + Q_D(NumKeyDia); + delete d->ui; } -bool NumKeyDia::eventFilter(QObject *, QEvent *event) -{ - if(event->type() == QEvent::MouseButtonPress) - { +NumKeyDia* NumKeyDia::instance() { + if(!singleton) + singleton = new NumKeyDia; + return singleton; +} + +bool NumKeyDia::eventFilter(QObject *, QEvent *event) { + Q_D(NumKeyDia); + if (event->type() == QEvent::MouseButtonPress) { auto *mouseEvent = static_cast(event); - m_point = mouseEvent->globalPos() - frameGeometry().topLeft(); - } - else if(event->type() == QEvent::MouseMove) - { + d->m_point = mouseEvent->globalPos() - frameGeometry().topLeft(); + } else if (event->type() == QEvent::MouseMove) { auto *mouseEvent = static_cast(event); - move(mouseEvent->globalPos() - m_point); + move(mouseEvent->globalPos() - d->m_point); } return false; } -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; +void NumKeyDia::setValue(const QString &value) { + Q_D(NumKeyDia); + d->value = value; + 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; } -QString &NumKeyDia::getValue() -{ - return value; +QString &NumKeyDia::getValue() { + Q_D(NumKeyDia); + return d->value; } -void NumKeyDia::on_btn_ok_clicked() -{ - QString _res = ui->lineEdit_input->text(); - if(_res.isEmpty()) - { - _res = QStringLiteral("0"); - } - - value = _res; - +void NumKeyDia::on_btn_ok_clicked() { + Q_D(NumKeyDia); + QString res = d->ui->lineEdit_input->text(); + d->value = res.isEmpty() ? "0" : res; closeKeyBoard(); } -void NumKeyDia::on_btn_cancel_clicked() -{ +void NumKeyDia::on_btn_cancel_clicked() { closeKeyBoard(); } -void NumKeyDia::on_btn_clear_clicked() -{ - m_firstInputFlag = false; - const int currentPosition = ui->lineEdit_input->cursorPosition(); - ui->lineEdit_input->setCursorPosition(qMax(0, currentPosition - 1)); - ui->lineEdit_input->setFocus(); +void NumKeyDia::on_btn_clear_clicked() { + Q_D(NumKeyDia); + 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::on_btn_back_clicked() -{ - m_firstInputFlag = false; - - int _index = ui->lineEdit_input->cursorPosition(); - QString _currentText = ui->lineEdit_input->text(); +void NumKeyDia::on_btn_back_clicked() { + Q_D(NumKeyDia); + d->m_firstInputFlag = false; + int index = d->ui->lineEdit_input->cursorPosition(); + QString text = d->ui->lineEdit_input->text(); - if(_currentText.isEmpty()) - { - ui->lineEdit_input->setFocus(); + if (index > 0) { + text.remove(index - 1, 1); + d->ui->lineEdit_input->setText(text); + d->ui->lineEdit_input->setCursorPosition(index - 1); } - - if(_index != 0) - { - _currentText.remove(_index - 1, 1); - ui->lineEdit_input->setText(_currentText); - } - - ui->lineEdit_input->setFocus(); - ui->lineEdit_input->setCursorPosition(qMax(0, _index - 1)); + d->ui->lineEdit_input->setFocus(); } -void NumKeyDia::btn_input_clicked() -{ - auto *_btnClicked = qobject_cast(sender()); - if(!_btnClicked) - { - return; - } +void NumKeyDia::btn_input_clicked() { + Q_D(NumKeyDia); + auto *btn = qobject_cast(sender()); + if (!btn) return; - if(_btnClicked->property("isModeSwitch").toBool()) - { - const auto nextPage = (m_inputPage == InputPage::NumberPage) - ? InputPage::SymbolPage - : InputPage::NumberPage; - setInputPage(nextPage); - ui->lineEdit_input->setFocus(); + if (btn->property("isModeSwitch").toBool()) { + auto nextPage = (d->m_inputPage == NumKeyDiaPrivate::InputPage::NumberPage) + ? NumKeyDiaPrivate::InputPage::SymbolPage + : NumKeyDiaPrivate::InputPage::NumberPage; + d->setInputPage(nextPage); + d->ui->lineEdit_input->setFocus(); return; } - if(m_firstInputFlag) - { - ui->lineEdit_input->clear(); - m_firstInputFlag = false; + if (d->m_firstInputFlag) { + d->ui->lineEdit_input->clear(); + d->m_firstInputFlag = false; } - const QString _inputValue = _btnClicked->property("inputValue").toString(); - if(_inputValue.isEmpty()) - { - ui->lineEdit_input->setFocus(); - return; - } + QString input = btn->property("inputValue").toString(); + if (input.isEmpty()) return; - int _index = ui->lineEdit_input->cursorPosition(); - QString _currentText = ui->lineEdit_input->text(); - - _currentText.insert(_index, _inputValue); - ui->lineEdit_input->setText(_currentText); - ui->lineEdit_input->setFocus(); - ui->lineEdit_input->setCursorPosition(_index + _inputValue.size()); + int index = d->ui->lineEdit_input->cursorPosition(); + QString text = d->ui->lineEdit_input->text(); + text.insert(index, input); + d->ui->lineEdit_input->setText(text); + d->ui->lineEdit_input->setFocus(); + d->ui->lineEdit_input->setCursorPosition(index + input.size()); } -void NumKeyDia::closeKeyBoard() -{ +void NumKeyDia::closeKeyBoard() { this->close(); } -void NumKeyDia::setInputPage(InputPage page) -{ - m_inputPage = page; - refreshInputButtons(); -} - -void NumKeyDia::refreshInputButtons() -{ - if(m_inputPage == InputPage::NumberPage) - { - configureInputButton(ui->btn_1, QStringLiteral("1"), QStringLiteral("1"), true); - configureInputButton(ui->btn_2, QStringLiteral("2"), QStringLiteral("2"), true); - configureInputButton(ui->btn_3, QStringLiteral("3"), QStringLiteral("3"), true); - configureInputButton(ui->btn_4, QStringLiteral("4"), QStringLiteral("4"), true); - configureInputButton(ui->btn_5, QStringLiteral("5"), QStringLiteral("5"), true); - configureInputButton(ui->btn_6, QStringLiteral("6"), QStringLiteral("6"), true); - configureInputButton(ui->btn_7, QStringLiteral("7"), QStringLiteral("7"), true); - 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; - } - - configureInputButton(ui->btn_1, QStringLiteral("/"), QStringLiteral("/"), true); - configureInputButton(ui->btn_2, QStringLiteral("-"), QStringLiteral("-"), true); - configureInputButton(ui->btn_3, QStringLiteral(":"), QStringLiteral(":"), true); - 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); +namespace KeyBoard { +NumKeyDia *app() { + return NumKeyDia::instance(); } - -void NumKeyDia::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); } - -namespace KeyBoard -{ -NumKeyDia *app() -{ - return NumKeyDia::instance(); -}; -}; diff --git a/numkeydia.h b/numkeydia.h index 5c28760..c20d152 100644 --- a/numkeydia.h +++ b/numkeydia.h @@ -3,72 +3,47 @@ #include "NumKeyBoard_global.h" #include -#include +#include -class QPushButton; - -namespace Ui -{ +// 向前声明 +namespace Ui { class NumKeyDia; } +class NumKeyDiaPrivate; class NUMKEYBOARD_EXPORT NumKeyDia : public QDialog { Q_OBJECT + // 声明私有类 + Q_DECLARE_PRIVATE(NumKeyDia) public: explicit NumKeyDia(QWidget *parent = nullptr); ~NumKeyDia(); - static NumKeyDia *instance() - { - return singleton; - } + static NumKeyDia *instance(); void setValue(const QString &value); QString &getValue(); protected: - virtual bool eventFilter(QObject *obj, QEvent *event) override; + bool eventFilter(QObject *obj, QEvent *event) override; private slots: void on_btn_ok_clicked(); - void on_btn_cancel_clicked(); - void on_btn_clear_clicked(); - void on_btn_back_clicked(); - void btn_input_clicked(); - void closeKeyBoard(); private: - enum class InputPage - { - NumberPage, - SymbolPage - }; - - void setInputPage(InputPage page); - void refreshInputButtons(); - void configureInputButton(QPushButton *button, - const QString &label, - const QString &value, - bool enabled, - bool isModeSwitch = false); - - Ui::NumKeyDia *ui; - + // 使用 QScopedPointer 管理私有实现类 + QScopedPointer d_ptr; static NumKeyDia *singleton; - QString value = QString(); - - QPoint m_point; - - bool m_firstInputFlag = true; - InputPage m_inputPage = InputPage::NumberPage; + // 禁用拷贝 + Q_DISABLE_COPY(NumKeyDia) }; namespace KeyBoard diff --git a/numkeydia.ui b/numkeydia.ui index 1feeba8..feca137 100644 --- a/numkeydia.ui +++ b/numkeydia.ui @@ -82,7 +82,7 @@ - border-image: url(:/Images/keyboard.svg); + border-image: url(:/keyboard.svg);