数字键盘
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

240 lines
7.4 KiB

#include "numkeydia.h"
#include "ui_numkeydia.h"
#include <QDebug>
#include <QFile>
#include <QMouseEvent>
#include <QPushButton>
#include <QShortcut>
#include <QTextStream>
// --- 私有类定义 ---
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)) {
QTextStream stream(&file);
q_ptr->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)
, d_ptr(new NumKeyDiaPrivate(this)) // 初始化 d_ptr
{
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<QPushButton *>();
for (auto *btn : btnList) {
connect(btn, &QPushButton::clicked, this, &NumKeyDia::btn_input_clicked);
btn->setFocusPolicy(Qt::NoFocus);
}
auto *okShortcut = new QShortcut(QKeySequence(Qt::Key_Return), this);
connect(okShortcut, &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("<"));
d->setInputPage(NumKeyDiaPrivate::InputPage::NumberPage);
}
NumKeyDia::~NumKeyDia() {
if (singleton == this) singleton = nullptr;
// QScopedPointer 会自动删除 d_ptr,但 Ui 需手动销毁(如果没设置 parent)
Q_D(NumKeyDia);
delete d->ui;
}
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<QMouseEvent *>(event);
d->m_point = mouseEvent->globalPos() - frameGeometry().topLeft();
} else if (event->type() == QEvent::MouseMove) {
auto *mouseEvent = static_cast<QMouseEvent *>(event);
move(mouseEvent->globalPos() - d->m_point);
}
return false;
}
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() {
Q_D(NumKeyDia);
return d->value;
}
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() {
closeKeyBoard();
}
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() {
Q_D(NumKeyDia);
d->m_firstInputFlag = false;
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::btn_input_clicked() {
Q_D(NumKeyDia);
auto *btn = qobject_cast<QPushButton *>(sender());
if (!btn) return;
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 (d->m_firstInputFlag) {
d->ui->lineEdit_input->clear();
d->m_firstInputFlag = false;
}
QString input = btn->property("inputValue").toString();
if (input.isEmpty()) return;
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() {
this->close();
}
namespace KeyBoard {
NumKeyDia *app() {
return NumKeyDia::instance();
}
}