|
2 | 2 |
|
3 | 3 | #include <QtWidgets>
|
4 | 4 |
|
5 |
| -PasswordLineEdit::PasswordLineEdit(QWidget *parent) |
6 |
| - : QLineEdit(parent) |
| 5 | +#ifdef Q_OS_WIN |
| 6 | +#include <windows.h> |
| 7 | +#endif |
| 8 | + |
| 9 | +bool isCapsLockOn() |
7 | 10 | {
|
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 | +} |
14 | 18 |
|
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); |
17 | 29 |
|
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"); |
28 | 32 |
|
| 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 |
29 | 72 | onShowPassword(false);
|
30 | 73 | }
|
31 | 74 |
|
| 75 | +PasswordLineEdit::~PasswordLineEdit() {} |
| 76 | + |
32 | 77 | void PasswordLineEdit::onShowPassword(bool state)
|
33 | 78 | {
|
34 | 79 | if (state) {
|
35 | 80 | setEchoMode(Normal);
|
36 |
| - m_toolButton->setIcon(m_hidden_icon); |
| 81 | + d_ptr->toolButton->setIcon(d_ptr->hiddenIcon); |
37 | 82 | } else {
|
38 | 83 | 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 | + } |
40 | 105 | }
|
| 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); |
41 | 132 | }
|
0 commit comments