Skip to content

Commit 719982c

Browse files
committed
[新增QtQuick密码输入框控件]: 添加全新的PasswordInputQuick QtQuick组件,提供现代化的密码输入体验,支持显示/隐藏切换和自定义图标
- **新增密码输入组件**: 创建PasswordInput.qml QtQuick组件,提供带显示/隐藏切换功能的密码输入框,支持自定义图标、占位符文本和输入验证 - **完善示例应用**: 添加Main.qml演示文件,展示密码输入框的各种用法,包括基本使用、自定义图标、批量操作和密码验证功能 - **集成构建系统**: 更新根目录CMakeLists.txt,将PasswordInputQuick模块纳入构建体系,确保组件可正确编译和部署 - **更新项目文档**: 在README.md中添加PasswordInputQuick控件介绍和截图,保持项目文档的完整性和时效性 - **提供完整示例**: 实现完整的演示应用程序,包含状态显示、批量控制、自定义图标设置等实用功能,方便用户快速上手
1 parent be50b65 commit 719982c

7 files changed

Lines changed: 449 additions & 0 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,10 @@ void ThreadedTcpServer::incomingConnection(qintptr socketDescriptor)
169169
170170
- <img src="src/NavigationProgressBarQuick/images/navigation_progress.png" width="800" alt="导航进度条截图">
171171
172+
### [PasswordInputQuick](src/PasswordInputQuick/) - 密码输入框控件(QtQuick版本)
173+
174+
- <img src="src/PasswordInputQuick/images/password_input.png" width="600" alt="密码输入框截图">
175+
172176
### [PasswordLineEdit](src/PasswordLineEdit/) - 密码输入框控件
173177
174178
- 支持显示/隐藏密码切换功能

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ add_subdirectory(LoadingIndicatorQuick)
1616
add_subdirectory(LoadingOverlayQuick)
1717
add_subdirectory(NavigationProgressBar)
1818
add_subdirectory(NavigationProgressBarQuick)
19+
add_subdirectory(PasswordInputQuick)
1920
add_subdirectory(PasswordLineEdit)
2021
add_subdirectory(ProgressArc)
2122
add_subdirectory(ProgressBar)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
qt_add_executable(appPasswordInputQuick main.cc)
2+
target_link_libraries(appPasswordInputQuick PRIVATE Qt::Quick)
3+
4+
qt_add_qml_module(
5+
appPasswordInputQuick
6+
URI
7+
PasswordInputQuick
8+
VERSION
9+
1.0
10+
QML_FILES
11+
Main.qml
12+
PasswordInput.qml
13+
OUTPUT_DIRECTORY
14+
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/PasswordInputQuick")

src/PasswordInputQuick/Main.qml

Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
import QtQuick
2+
import QtQuick.Controls
3+
import QtQuick.Layouts
4+
import QtQuick.Controls.Fusion
5+
6+
ApplicationWindow {
7+
id: mainWindow
8+
width: 600
9+
height: 500
10+
visible: true
11+
title: qsTr("Password Input Quick Example")
12+
13+
ColumnLayout {
14+
anchors.fill: parent
15+
anchors.margins: 10
16+
17+
// 基本密码输入框
18+
GroupBox {
19+
title: qsTr("Basic Password Input")
20+
Layout.fillWidth: true
21+
22+
ColumnLayout {
23+
width: parent.width
24+
25+
PasswordInput {
26+
id: basicPasswordInput
27+
Layout.fillWidth: true
28+
Layout.preferredHeight: 50
29+
placeholderText: qsTr("Enter your password here")
30+
31+
onTextChanged: {
32+
mainWindow.updateStatus(qsTr("Basic password input updated"));
33+
}
34+
}
35+
}
36+
}
37+
38+
// 带自定义提示的密码框
39+
GroupBox {
40+
title: qsTr("Password Input with Custom Placeholder")
41+
Layout.fillWidth: true
42+
43+
ColumnLayout {
44+
width: parent.width
45+
46+
PasswordInput {
47+
id: customPasswordInput
48+
Layout.fillWidth: true
49+
Layout.preferredHeight: 50
50+
placeholderText: qsTr("Minimum 8 characters with special symbols")
51+
52+
onTextChanged: {
53+
mainWindow.updateStatus(qsTr("Custom password input updated"));
54+
}
55+
}
56+
}
57+
}
58+
59+
// 控制面板
60+
GroupBox {
61+
title: qsTr("Controls")
62+
Layout.fillWidth: true
63+
64+
GridLayout {
65+
columns: 3
66+
width: parent.width
67+
68+
// 显示所有密码按钮
69+
Button {
70+
text: qsTr("Show All Passwords")
71+
Layout.fillWidth: true
72+
onClicked: {
73+
mainWindow.showAllPasswords();
74+
mainWindow.updateStatus(qsTr("All passwords are now visible"));
75+
}
76+
}
77+
78+
// 隐藏所有密码按钮
79+
Button {
80+
text: qsTr("Hide All Passwords")
81+
Layout.fillWidth: true
82+
onClicked: {
83+
mainWindow.hideAllPasswords();
84+
mainWindow.updateStatus(qsTr("All passwords are now hidden"));
85+
}
86+
}
87+
88+
// 清除所有密码按钮
89+
Button {
90+
text: qsTr("Clear All Passwords")
91+
Layout.fillWidth: true
92+
onClicked: {
93+
mainWindow.clearAllPasswords();
94+
mainWindow.updateStatus(qsTr("All passwords cleared"));
95+
}
96+
}
97+
98+
// 验证按钮
99+
Button {
100+
text: qsTr("Validate Passwords")
101+
Layout.columnSpan: 3
102+
Layout.fillWidth: true
103+
onClicked: {
104+
mainWindow.validatePasswords();
105+
}
106+
}
107+
}
108+
}
109+
110+
// 自定义图标设置
111+
GroupBox {
112+
title: qsTr("Custom Icon Settings")
113+
Layout.fillWidth: true
114+
115+
RowLayout {
116+
width: parent.width
117+
118+
TextField {
119+
id: visibleIconInput
120+
Layout.fillWidth: true
121+
placeholderText: qsTr("Visible icon (text or emoji)")
122+
text: "👁️"
123+
}
124+
125+
TextField {
126+
id: hiddenIconInput
127+
Layout.fillWidth: true
128+
placeholderText: qsTr("Hidden icon (text or emoji)")
129+
text: "🔒"
130+
}
131+
132+
Button {
133+
text: qsTr("Apply Icons")
134+
onClicked: {
135+
mainWindow.applyCustomIcons();
136+
mainWindow.updateStatus(qsTr("Custom icons applied"));
137+
}
138+
}
139+
}
140+
}
141+
142+
// 状态显示
143+
GroupBox {
144+
title: qsTr("Status")
145+
Layout.fillWidth: true
146+
147+
Rectangle {
148+
width: parent.width
149+
radius: 4
150+
151+
Text {
152+
id: statusLabel
153+
anchors.centerIn: parent
154+
text: qsTr("Ready")
155+
font.pixelSize: 14
156+
horizontalAlignment: Text.AlignHCenter
157+
}
158+
}
159+
}
160+
161+
// 密码信息显示
162+
GroupBox {
163+
title: qsTr("Password Information")
164+
Layout.fillWidth: true
165+
166+
ColumnLayout {
167+
width: parent.width
168+
spacing: 5
169+
170+
Text {
171+
text: qsTr("Basic Input: ") + (basicPasswordInput.passwordVisible ? qsTr("Visible") : qsTr("Hidden")) + " | " + qsTr("Length: ") + basicPasswordInput.text.length
172+
font.pixelSize: 12
173+
}
174+
175+
Text {
176+
text: qsTr("Custom Input: ") + (customPasswordInput.passwordVisible ? qsTr("Visible") : qsTr("Hidden")) + " | " + qsTr("Length: ") + customPasswordInput.text.length
177+
font.pixelSize: 12
178+
}
179+
}
180+
}
181+
}
182+
183+
// 收集所有密码输入框
184+
function getAllPasswordInputs() {
185+
return [basicPasswordInput, customPasswordInput];
186+
}
187+
188+
// 显示所有密码
189+
function showAllPasswords() {
190+
var inputs = getAllPasswordInputs();
191+
for (var i = 0; i < inputs.length; i++) {
192+
if (!inputs[i].passwordVisible) {
193+
inputs[i].togglePasswordVisibility();
194+
}
195+
}
196+
}
197+
198+
// 隐藏所有密码
199+
function hideAllPasswords() {
200+
var inputs = getAllPasswordInputs();
201+
for (var i = 0; i < inputs.length; i++) {
202+
if (inputs[i].passwordVisible) {
203+
inputs[i].togglePasswordVisibility();
204+
}
205+
}
206+
}
207+
208+
// 清除所有密码
209+
function clearAllPasswords() {
210+
var inputs = getAllPasswordInputs();
211+
for (var i = 0; i < inputs.length; i++) {
212+
inputs[i].clear();
213+
}
214+
}
215+
216+
// 验证密码
217+
function validatePasswords() {
218+
var inputs = getAllPasswordInputs();
219+
var allValid = true;
220+
var messages = [];
221+
222+
for (var i = 0; i < inputs.length; i++) {
223+
var input = inputs[i];
224+
if (input.text.length > 0) {
225+
if (input.text.length < 6) {
226+
var inputName = input === basicPasswordInput ? qsTr("Basic input") : qsTr("Custom input");
227+
messages.push(qsTr("%1 is too short (minimum 6 characters)").arg(inputName));
228+
allValid = false;
229+
}
230+
}
231+
}
232+
233+
if (allValid && messages.length === 0) {
234+
updateStatus("" + qsTr("All passwords are valid"));
235+
} else if (messages.length === 0) {
236+
updateStatus("" + qsTr("No passwords to validate"));
237+
} else {
238+
updateStatus("" + messages.join("; "));
239+
}
240+
}
241+
242+
// 应用自定义图标
243+
function applyCustomIcons() {
244+
var inputs = getAllPasswordInputs();
245+
var visibleIcon = visibleIconInput.text.trim();
246+
var hiddenIcon = hiddenIconInput.text.trim();
247+
248+
if (visibleIcon !== "" && hiddenIcon !== "") {
249+
for (var i = 0; i < inputs.length; i++) {
250+
inputs[i].setToggleIcons(visibleIcon, hiddenIcon);
251+
}
252+
}
253+
}
254+
255+
// 更新状态
256+
function updateStatus(message) {
257+
statusLabel.text = message;
258+
}
259+
260+
// 组件加载完成后的初始化
261+
Component.onCompleted: {
262+
updateStatus(qsTr("Application started successfully"));
263+
}
264+
}

0 commit comments

Comments
 (0)