Skip to content

Commit 9b632ec

Browse files
committed
[增强 PasswordLineEdit 功能,添加 Caps Lock 状态提示]: 重构 PasswordLineEdit 组件,使用 Pimpl 模式优化实现细节,并在 Windows 平台下增加 Caps Lock 状态检测与提示功能,同时改进 UI 样式和交互体验。
- **PasswordLineEdit.pro**: 添加 Windows 平台下链接 user32 库的配置,支持 Caps Lock 检测功能 - **passwordlineedit.cc/hpp**: 使用 Pimpl 模式重构 PasswordLineEdit 类,隐藏实现细节 - **Caps Lock 检测功能**: 在 Windows 平台下实现 Caps Lock 状态检测(使用 GetKeyState 函数) - **提示标签功能**: 在密码输入框上方添加提示标签,显示 Caps Lock 状态(开启/关闭) - **事件过滤器**: 添加事件过滤器处理键盘释放事件和焦点进入事件,实时检测 Caps Lock 状态 - **UI 样式改进**: 使用正则表达式验证输入内容,限制特殊字符输入 - **计时器功能**: 添加计时器功能,3秒后自动隐藏 Caps Lock 提示标签 - **代码结构优化**: 重构构造函数和析构函数,分离 UI 设置和信号槽连接逻辑
1 parent dea563f commit 9b632ec

File tree

3 files changed

+126
-30
lines changed

3 files changed

+126
-30
lines changed

PasswordLineEdit/PasswordLineEdit.pro

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ HEADERS += \
1717
RESOURCES += \
1818
resources.qrc
1919

20+
win32: LIBS += -luser32
21+
2022
# Default rules for deployment.
2123
qnx: target.path = /tmp/$${TARGET}/bin
2224
else: unix:!android: target.path = /opt/$${TARGET}/bin

PasswordLineEdit/passwordlineedit.cc

Lines changed: 113 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,131 @@
22

33
#include <QtWidgets>
44

5-
PasswordLineEdit::PasswordLineEdit(QWidget *parent)
6-
: QLineEdit(parent)
5+
#ifdef Q_OS_WIN
6+
#include <windows.h>
7+
#endif
8+
9+
bool isCapsLockOn()
710
{
8-
setAttribute(Qt::WA_InputMethodEnabled, false);
9-
setStyleSheet("QLineEdit{ border:none; border-bottom: 1px solid #DDDDDD; color: #222222; "
10-
"padding-left:10px; font-size:14px; }"
11-
"QToolButton{ border: none; }");
12-
setPlaceholderText(tr("Please enter the password."));
13-
setMinimumSize(200, 30);
11+
#ifdef Q_OS_WIN
12+
return (GetKeyState(VK_CAPITAL) & 0x0001) != 0;
13+
#else
14+
qWarning() << "Unsupported platform";
15+
return false;
16+
#endif
17+
}
1418

15-
m_hidden_icon.addFile("://resources/hidden_password.png");
16-
m_view_icon.addFile("://resources/view_password.png");
19+
class PasswordLineEdit::PasswordLineEditPrivate
20+
{
21+
public:
22+
explicit PasswordLineEditPrivate(PasswordLineEdit *q)
23+
: q_ptr(q)
24+
{
25+
toolButton = new QToolButton(q_ptr);
26+
toolButton->setIconSize({25, 25});
27+
toolButton->setCursor(Qt::PointingHandCursor);
28+
toolButton->setCheckable(true);
1729

18-
m_toolButton = new QToolButton(this);
19-
m_toolButton->setIconSize(QSize(25, 25));
20-
m_toolButton->setCursor(Qt::PointingHandCursor);
21-
m_toolButton->setCheckable(true);
22-
connect(m_toolButton, &QToolButton::clicked, this, &PasswordLineEdit::onShowPassword);
23-
QHBoxLayout *layout = new QHBoxLayout(this);
24-
layout->setContentsMargins(1, 1, 10, 1);
25-
layout->setSpacing(0);
26-
layout->addStretch();
27-
layout->addWidget(m_toolButton);
30+
hiddenIcon.addFile("://resources/hidden_password.png");
31+
viewIcon.addFile("://resources/view_password.png");
2832

33+
labelPtr.reset(new QLabel);
34+
labelPtr->setWindowFlags(labelPtr->windowFlags() | Qt::ToolTip);
35+
labelPtr->setStyleSheet("QLabel{background: #909090; padding:5px; color: #E60000;"
36+
"font-size:12px; font-weight:bold;}");
37+
labelPtr->hide();
38+
timer = new QTimer(q_ptr);
39+
timer->setInterval(3000);
40+
}
41+
42+
~PasswordLineEditPrivate() {}
43+
44+
void showLabel(const QString &text)
45+
{
46+
labelPtr->setText(text);
47+
labelPtr->show();
48+
auto point = q_ptr->mapToGlobal(QPoint(10, -labelPtr->height() / 2));
49+
labelPtr->move(point);
50+
timer->start();
51+
}
52+
53+
PasswordLineEdit *q_ptr;
54+
55+
QToolButton *toolButton;
56+
QIcon hiddenIcon;
57+
QIcon viewIcon;
58+
59+
QScopedPointer<QLabel> labelPtr;
60+
QTimer *timer;
61+
};
62+
63+
PasswordLineEdit::PasswordLineEdit(QWidget *parent)
64+
: QLineEdit(parent)
65+
, d_ptr(new PasswordLineEditPrivate(this))
66+
{
67+
setupUI();
68+
buildConnect();
69+
#ifdef Q_OS_WIN
70+
installEventFilter(this);
71+
#endif
2972
onShowPassword(false);
3073
}
3174

75+
PasswordLineEdit::~PasswordLineEdit() {}
76+
3277
void PasswordLineEdit::onShowPassword(bool state)
3378
{
3479
if (state) {
3580
setEchoMode(Normal);
36-
m_toolButton->setIcon(m_hidden_icon);
81+
d_ptr->toolButton->setIcon(d_ptr->hiddenIcon);
3782
} else {
3883
setEchoMode(Password);
39-
m_toolButton->setIcon(m_view_icon);
84+
d_ptr->toolButton->setIcon(d_ptr->viewIcon);
85+
}
86+
}
87+
88+
bool PasswordLineEdit::eventFilter(QObject *watched, QEvent *event)
89+
{
90+
if (watched == this) {
91+
switch (event->type()) {
92+
case QEvent::KeyRelease: {
93+
auto *keyEvent = static_cast<QKeyEvent *>(event);
94+
if (keyEvent->key() == Qt::Key_CapsLock) {
95+
d_ptr->showLabel(isCapsLockOn() ? tr("Caps Lock On") : tr("Caps Lock Off"));
96+
}
97+
} break;
98+
case QEvent::FocusIn:
99+
if (isCapsLockOn()) {
100+
d_ptr->showLabel(tr("Caps Lock On"));
101+
}
102+
break;
103+
default: break;
104+
}
40105
}
106+
return QLineEdit::eventFilter(watched, event);
107+
}
108+
109+
void PasswordLineEdit::setupUI()
110+
{
111+
setStyleSheet("QLineEdit{border:none; border-bottom: 1px solid #DDDDDD;"
112+
"color: #222222; padding-left:10px; font-size:14px; }"
113+
"QToolButton{border: none;}");
114+
setPlaceholderText(tr("Please enter the password."));
115+
setMinimumSize(200, 30);
116+
117+
QRegularExpression regExp("[a-zA-Z0-9!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~]+");
118+
setValidator(new QRegularExpressionValidator(regExp, this));
119+
setAttribute(Qt::WA_InputMethodEnabled, false);
120+
121+
auto *layout = new QHBoxLayout(this);
122+
layout->setContentsMargins(1, 1, 10, 1);
123+
layout->setSpacing(0);
124+
layout->addStretch();
125+
layout->addWidget(d_ptr->toolButton);
126+
}
127+
128+
void PasswordLineEdit::buildConnect()
129+
{
130+
connect(d_ptr->toolButton, &QToolButton::clicked, this, &PasswordLineEdit::onShowPassword);
131+
connect(d_ptr->timer, &QTimer::timeout, d_ptr->labelPtr.data(), &QLabel::hide);
41132
}

PasswordLineEdit/passwordlineedit.hpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
#ifndef PASSWORDLINEEDIT_HPP
2-
#define PASSWORDLINEEDIT_HPP
1+
#pragma once
32

43
#include <QLineEdit>
54

@@ -8,14 +7,18 @@ class PasswordLineEdit : public QLineEdit
87
Q_OBJECT
98
public:
109
explicit PasswordLineEdit(QWidget *parent = nullptr);
10+
~PasswordLineEdit() override;
1111

1212
private slots:
13-
void onShowPassword(bool);
13+
void onShowPassword(bool state);
14+
15+
protected:
16+
bool eventFilter(QObject *watched, QEvent *event) override;
1417

1518
private:
16-
QToolButton *m_toolButton;
17-
QIcon m_hidden_icon;
18-
QIcon m_view_icon;
19-
};
19+
void setupUI();
20+
void buildConnect();
2021

21-
#endif // PASSWORDLINEEDIT_HPP
22+
class PasswordLineEditPrivate;
23+
QScopedPointer<PasswordLineEditPrivate> d_ptr;
24+
};

0 commit comments

Comments
 (0)