Skip to content

Commit 02bb220

Browse files
committed
[重构PasswordLineEdit控件并完善示例程序]: 全面升级密码输入框控件功能,增强用户体验和代码可维护性,提供完整的演示界面
- **控件功能增强**: 重构PasswordLineEdit类,新增CapsLock状态检测警告、自定义图标支持、工具提示时长设置等高级功能,提升密码输入安全性 - **演示程序完善**: 完全重写mainwindow.cc,创建功能丰富的演示界面,包含多个密码输入场景、批量操作控制和实时状态反馈 - **代码结构优化**: 采用现代C++编程规范,移除资源文件依赖,使用系统图标替代自定义图片,简化项目配置和构建流程 - **项目配置清理**: 更新CMakeLists.txt和.pro文件,移除不必要的资源引用,统一目标命名规范,优化构建系统配置 - **文档更新同步**: 更新README.md中PasswordLineEdit章节,详细描述新功能特性,替换为新的界面截图,保持文档与代码同步
1 parent 179020e commit 02bb220

14 files changed

Lines changed: 350 additions & 108 deletions

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,13 @@ void ThreadedTcpServer::incomingConnection(qintptr socketDescriptor)
171171
- 自适应布局,响应窗口尺寸变化
172172
- <img src="src/NavigationProgressBar/images/navigation_progress.png" width="800" alt="导航进度条截图">
173173
174-
### [PasswordLineEdit](src/PasswordLineEdit/) - 密码输入字段
174+
## [PasswordLineEdit](src/PasswordLineEdit/) - 密码输入框控件
175175
176-
- 安全密码输入
177-
- 切换可见性
178-
- <img src="src/PasswordLineEdit/picture/HiddenPassword.png" width="200" alt="隐藏密码">
179-
<img src="src/PasswordLineEdit/picture/ShowPassword.png" width="200" alt="显示密码">
176+
- 支持显示/隐藏密码切换功能
177+
- 自动检测CapsLock状态并显示警告提示
178+
- 可自定义图标、提示时长和警告功能
179+
- 提供密码验证和批量操作支持
180+
- <img src="src/PasswordLineEdit/images/password_line_edit.png" width="600" alt="密码输入框截图">
180181
181182
### [ProgressArc](src/ProgressArc/) - 圆形进度指示器
182183
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
set(PROJECT_SOURCES main.cpp mainwindow.cpp mainwindow.h
22
navigationprogressbar.h navigationprogressbar.cpp)
33

4-
qt_add_executable(NavigationProgressBar ${PROJECT_SOURCES})
5-
target_link_libraries(NavigationProgressBar PRIVATE Qt::Widgets)
4+
qt_add_executable(navigation_progress ${PROJECT_SOURCES})
5+
target_link_libraries(navigation_progress PRIVATE Qt::Widgets)
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
set(PROJECT_SOURCES main.cc mainwindow.cc mainwindow.hpp passwordlineedit.cc
22
passwordlineedit.hpp)
33

4-
qt_add_resources(PROJECT_SOURCES resources.qrc)
5-
64
qt_add_executable(PasswordLineEdit ${PROJECT_SOURCES})
75
target_link_libraries(PasswordLineEdit PRIVATE Qt::Widgets)

src/PasswordLineEdit/PasswordLineEdit.pro

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@ HEADERS += \
1313
mainwindow.hpp \
1414
passwordlineedit.hpp
1515

16-
17-
RESOURCES += \
18-
resources.qrc
19-
2016
win32: LIBS += -luser32
2117

2218
DESTDIR = $$RUNTIME_OUTPUT_DIRECTORY
18.5 KB
Loading

src/PasswordLineEdit/mainwindow.cc

Lines changed: 178 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,184 @@
66
MainWindow::MainWindow(QWidget *parent)
77
: QMainWindow(parent)
88
{
9-
auto widget = new QWidget(this);
10-
auto passwordLineEdit = new PasswordLineEdit(this);
11-
passwordLineEdit->setMinimumHeight(50);
12-
auto layout = new QHBoxLayout(widget);
13-
layout->addWidget(passwordLineEdit);
14-
setCentralWidget(widget);
15-
setMinimumSize(300, 130);
9+
// 创建主窗口部件
10+
auto *centralWidget = new QWidget(this);
11+
setCentralWidget(centralWidget);
12+
13+
// 创建主布局
14+
auto *mainLayout = new QVBoxLayout(centralWidget);
15+
16+
// 创建多个密码输入框演示不同功能
17+
auto createPasswordField = [this](const QString &labelText,
18+
const QString &placeholder = "") -> auto * {
19+
auto *group = new QGroupBox(labelText, this);
20+
auto *layout = new QVBoxLayout(group);
21+
22+
auto *passwordEdit = new PasswordLineEdit(this);
23+
if (!placeholder.isEmpty()) {
24+
passwordEdit->setPlaceholderText(placeholder);
25+
}
26+
27+
layout->addWidget(passwordEdit);
28+
return group;
29+
};
30+
31+
// 基本密码输入框
32+
mainLayout->addWidget(createPasswordField("Basic Password Field", "Enter your password here"));
33+
34+
// 带自定义提示的密码框
35+
auto *customPlaceholderGroup = new QGroupBox("Password Field with Custom Placeholder", this);
36+
auto *customLayout = new QVBoxLayout(customPlaceholderGroup);
37+
auto *customPasswordEdit = new PasswordLineEdit(this);
38+
customPasswordEdit->setPlaceholderText("Minimum 8 characters with special symbols");
39+
customLayout->addWidget(customPasswordEdit);
40+
mainLayout->addWidget(customPlaceholderGroup);
41+
42+
// 禁用CapsLock警告的密码框
43+
auto *noCapsLockGroup = new QGroupBox("Password Field without CapsLock Warning", this);
44+
auto *noCapsLayout = new QVBoxLayout(noCapsLockGroup);
45+
auto *noCapsPasswordEdit = new PasswordLineEdit(this);
46+
noCapsPasswordEdit->setCapsLockWarningEnabled(false);
47+
noCapsPasswordEdit->setPlaceholderText("CapsLock warning disabled for this field");
48+
noCapsLayout->addWidget(noCapsPasswordEdit);
49+
mainLayout->addWidget(noCapsLockGroup);
50+
51+
// 控制面板
52+
auto *controlGroup = new QGroupBox("Controls", this);
53+
auto *controlLayout = new QGridLayout(controlGroup);
54+
55+
// CapsLock警告开关
56+
auto *capsLockCheckbox = new QCheckBox("Enable CapsLock Warning", this);
57+
capsLockCheckbox->setChecked(true);
58+
controlLayout->addWidget(capsLockCheckbox, 0, 0);
59+
60+
// 显示所有密码按钮
61+
auto *showAllButton = new QPushButton("Show All Passwords", this);
62+
controlLayout->addWidget(showAllButton, 0, 1);
63+
64+
// 隐藏所有密码按钮
65+
auto *hideAllButton = new QPushButton("Hide All Passwords", this);
66+
controlLayout->addWidget(hideAllButton, 0, 2);
67+
68+
// 清除所有密码按钮
69+
auto *clearAllButton = new QPushButton("Clear All Passwords", this);
70+
controlLayout->addWidget(clearAllButton, 1, 0);
71+
72+
// 验证按钮
73+
auto *validateButton = new QPushButton("Validate Passwords", this);
74+
controlLayout->addWidget(validateButton, 1, 1);
75+
76+
// 工具提示时长设置
77+
auto *tooltipDurationSlider = new QSlider(Qt::Horizontal, this);
78+
tooltipDurationSlider->setRange(1000, 10000);
79+
tooltipDurationSlider->setValue(3000);
80+
auto *durationLabel = new QLabel("Tooltip Duration: 3000ms", this);
81+
controlLayout->addWidget(new QLabel("Tooltip Duration:", this), 2, 0);
82+
controlLayout->addWidget(tooltipDurationSlider, 2, 1);
83+
controlLayout->addWidget(durationLabel, 2, 2);
84+
85+
mainLayout->addWidget(controlGroup);
86+
87+
// 状态显示
88+
auto *statusGroup = new QGroupBox("Status", this);
89+
auto *statusLayout = new QVBoxLayout(statusGroup);
90+
auto *statusLabel = new QLabel("Ready", this);
91+
statusLabel->setAlignment(Qt::AlignCenter);
92+
statusLayout->addWidget(statusLabel);
93+
mainLayout->addWidget(statusGroup);
94+
95+
// 收集所有密码输入框
96+
QList<PasswordLineEdit *> passwordEdits;
97+
passwordEdits << customPasswordEdit << noCapsPasswordEdit;
98+
99+
// 动态查找所有PasswordLineEdit实例
100+
auto findAllPasswordEdits = [this]() {
101+
QList<PasswordLineEdit *> edits;
102+
for (auto *child : findChildren<PasswordLineEdit *>()) {
103+
edits.append(child);
104+
}
105+
return edits;
106+
};
107+
108+
// 信号连接
109+
110+
// CapsLock警告开关
111+
connect(capsLockCheckbox, &QCheckBox::toggled, this, [findAllPasswordEdits](bool enabled) {
112+
for (auto *edit : findAllPasswordEdits()) {
113+
edit->setCapsLockWarningEnabled(enabled);
114+
}
115+
});
116+
117+
// 显示所有密码
118+
connect(showAllButton, &QPushButton::clicked, this, [findAllPasswordEdits]() {
119+
for (auto *edit : findAllPasswordEdits()) {
120+
edit->setEchoMode(QLineEdit::Normal);
121+
// 由于原代码没有提供直接设置显示状态的方法,我们通过模拟按钮点击来实现
122+
// 在实际使用中,如果PasswordLineEdit提供了togglePasswordVisibility()方法,应该使用它
123+
}
124+
});
125+
126+
// 隐藏所有密码
127+
connect(hideAllButton, &QPushButton::clicked, this, [findAllPasswordEdits]() {
128+
for (auto *edit : findAllPasswordEdits()) {
129+
edit->setEchoMode(QLineEdit::Password);
130+
}
131+
});
132+
133+
// 清除所有密码
134+
connect(clearAllButton, &QPushButton::clicked, this, [findAllPasswordEdits]() {
135+
for (auto *edit : findAllPasswordEdits()) {
136+
edit->clear();
137+
}
138+
});
139+
140+
// 验证密码
141+
connect(validateButton, &QPushButton::clicked, this, [findAllPasswordEdits, statusLabel]() {
142+
bool allValid = true;
143+
QStringList messages;
144+
145+
for (auto *edit : findAllPasswordEdits()) {
146+
if (!edit->text().isEmpty()) {
147+
if (edit->text().length() < 6) {
148+
messages.append(QString("'%1' is too short (min 6 characters)")
149+
.arg(edit->placeholderText().left(20)));
150+
allValid = false;
151+
}
152+
}
153+
}
154+
155+
if (allValid && messages.isEmpty()) {
156+
statusLabel->setText("✓ All passwords are valid");
157+
} else if (messages.isEmpty()) {
158+
statusLabel->setText("ℹ No passwords to validate");
159+
} else {
160+
statusLabel->setText("" + messages.join("; "));
161+
}
162+
});
163+
164+
// 工具提示时长设置
165+
connect(tooltipDurationSlider,
166+
&QSlider::valueChanged,
167+
this,
168+
[durationLabel, findAllPasswordEdits](int value) {
169+
durationLabel->setText(QString("Tooltip Duration: %1ms").arg(value));
170+
for (auto *edit : findAllPasswordEdits()) {
171+
edit->setToolTipDuration(value);
172+
}
173+
});
174+
175+
// 密码输入框文本变化连接
176+
auto updateStatusOnTextChange = [statusLabel]() {
177+
statusLabel->setText("Password field updated");
178+
};
179+
180+
for (auto *edit : findAllPasswordEdits()) {
181+
connect(edit, &QLineEdit::textChanged, this, updateStatusOnTextChange);
182+
}
183+
184+
// 窗口设置
185+
setWindowTitle("PasswordLineEdit Demonstration");
186+
resize(600, 450);
16187
}
17188

18189
MainWindow::~MainWindow() {}
Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,11 @@
1-
#ifndef MAINWINDOW_HPP
2-
#define MAINWINDOW_HPP
1+
#pragma once
32

4-
#include <QtCore/qglobal.h>
5-
#if QT_VERSION >= 0x050000
6-
#include <QtWidgets/QMainWindow>
7-
#else
8-
#include <QtGui/QMainWindow>
9-
#endif
3+
#include <QMainWindow>
104

115
class MainWindow : public QMainWindow
126
{
137
Q_OBJECT
14-
158
public:
169
explicit MainWindow(QWidget *parent = nullptr);
1710
~MainWindow() override;
1811
};
19-
20-
#endif // MAINWINDOW_HPP

0 commit comments

Comments
 (0)