Skip to content

Commit aa3fad7

Browse files
committed
[重构LoadingIndicator组件并优化项目结构]: 全面重构加载指示器组件,增加多种动画样式和自定义功能,同时移除LogAsynchronous模块并优化代码质量
- **LoadingIndicator组件重构**: 完全重写加载指示器实现,新增旋转圆点、脉冲圆圈、跳动条和自定义GIF四种动画样式,提供丰富的属性控制和信号通知机制 - **项目模块清理**: 移除重复的LogAsynchronous异步日志模块,统一引用Qt-App项目中的LogAsync实现,避免代码重复和维护负担 - **代码质量提升**: 修复多个模块中的lambda表达式捕获问题,将`[=]`改为具体变量捕获,消除潜在的悬空引用风险,提高代码安全性 - **资源文件规范化**: 统一LoadingIndicator模块的资源文件命名,将`resource.qrc`重命名为`resources.qrc`,保持项目资源管理的一致性 - **构建系统优化**: 更新CMakeLists.txt和.pro文件,移除已删除模块的构建配置,确保编译系统与代码结构同步 - **文档同步更新**: 全面更新README.md文档,详细描述新LoadingIndicator组件的特性和使用方法,提供准确的模块说明和示例截图
1 parent 633dd84 commit aa3fad7

24 files changed

Lines changed: 855 additions & 650 deletions

README.md

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -104,40 +104,24 @@
104104
- 类型安全,提供便捷创建函数
105105
- 适用于异步操作和事件处理场景
106106

107-
### [LoadingIndicator](src/LoadingIndicator/) - 加载动画
108-
109-
- 动画加载指示器
110-
- 支持 GIF 动画
111-
- <img src="src/LoadingIndicator/picture/LoadingIndicator.jpg" width="400" alt="加载指示器">
112-
113-
### [LogAsynchronous](src/LogAsynchronous/) - 异步日志系统
114-
115-
一个高性能的异步日志库,采用生产者-消费者模型,专门解决多线程环境下同步写日志的性能瓶颈问题。
116-
117-
#### 核心特性
118-
119-
- **前后端分离**:应用程序线程只将日志添加到内存缓冲区,专用日志线程负责写入磁盘
120-
- **无阻塞设计**:写日志操作不会阻塞应用程序主线程
121-
- **双滚动策略**:支持按文件大小(接近1GB)和按时间(每日零点)自动滚动日志文件
122-
123-
#### 文件命名规范
124-
125-
- 格式:`应用名.时间.主机名.进程ID.log[.序号]`
126-
- 示例:
127-
- `MyApp.2023-10-15-14-30-25.HOSTNAME.12345.log` (基础文件)
128-
- `MyApp.2023-10-15-14-30-25.HOSTNAME.12345.log.1` (滚动文件)
129-
130-
#### 日志格式
131-
132-
结构化日志格式,包含丰富上下文信息:
133-
134-
```
135-
2023-10-15 14:30:25.918 28456 [Info] 用户登录成功 File:(main.cpp) Line:(42)
136-
```
137-
138-
包含时间戳(毫秒)、线程ID、日志级别、消息内容和源代码位置。
139-
140-
此模块与[Qt-App项目中的日志实现](https://github.com/RealChuan/Qt-App/blob/main/src/utils/logasync.h)共享相同设计理念,建议集成时参考两个实现选择最适合的版本。
107+
### [LoadingIndicator](src/LoadingIndicator/) - 加载指示器控件
108+
109+
- 支持多种动画样式:旋转圆点、脉冲圆圈、跳动条、自定义GIF
110+
- 自适应窗口大小,自动居中显示
111+
- 可自定义文本、颜色、动画速度等属性
112+
- 支持信号通知动画开始和结束状态
113+
- 提供完整的属性接口和动画控制
114+
- 半透明背景设计,禁止父窗口交互
115+
- <img src="src/LoadingIndicator/images/loading_indicator.png" width="450" alt="加载指示器截图">
116+
117+
### [LogAsync](https://github.com/RealChuan/Qt-App/blob/main/src/utils/logasync.h) - 异步日志记录系统
118+
119+
- 独立线程处理日志写入,避免阻塞主线程
120+
- 支持控制台输出、文件记录或两者同时输出
121+
- 按大小和时间自动滚动日志文件,支持自动清理旧文件
122+
- 可设置不同日志级别(Debug、Info、Warning、Error、Fatal)
123+
- 控制台输出长度限制,避免过长日志刷屏
124+
- 内置信号槽机制,确保多线程环境下的数据安全
141125

142126
### [MulClient](src/MulClient/) - 多线程 TCP 客户端
143127

src/ButtonIconStateManager/mainwindow.cc

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -137,58 +137,64 @@ MainWindow::MainWindow(QWidget *parent)
137137
// 连接信号和槽
138138

139139
// 禁用状态控制
140-
connect(disableCheckbox, &QCheckBox::toggled, this, [=](bool checked) {
141-
button1->setDisabled(checked);
142-
button2->setDisabled(checked);
143-
button3->setDisabled(checked);
144-
button4->setDisabled(checked);
145-
button5->setDisabled(checked);
146-
147-
if (checked) {
148-
statusLabel->setText(tr("All buttons are disabled"));
149-
} else {
150-
statusLabel->setText(tr("All buttons are enabled"));
151-
}
152-
});
140+
connect(disableCheckbox,
141+
&QCheckBox::toggled,
142+
this,
143+
[button1, button2, button3, button4, button5, statusLabel](bool checked) {
144+
button1->setDisabled(checked);
145+
button2->setDisabled(checked);
146+
button3->setDisabled(checked);
147+
button4->setDisabled(checked);
148+
button5->setDisabled(checked);
149+
150+
if (checked) {
151+
statusLabel->setText(tr("All buttons are disabled"));
152+
} else {
153+
statusLabel->setText(tr("All buttons are enabled"));
154+
}
155+
});
153156

154157
// 重置按钮状态
155-
connect(resetButton, &QPushButton::clicked, this, [=]() {
156-
button1->setChecked(false);
157-
button2->setChecked(false);
158-
button3->setChecked(false);
159-
button4->setChecked(false);
160-
button5->setChecked(false);
161-
statusLabel->setText(tr("All buttons reset to normal state"));
162-
});
158+
connect(resetButton,
159+
&QPushButton::clicked,
160+
this,
161+
[button1, button2, button3, button4, button5, statusLabel]() {
162+
button1->setChecked(false);
163+
button2->setChecked(false);
164+
button3->setChecked(false);
165+
button4->setChecked(false);
166+
button5->setChecked(false);
167+
statusLabel->setText(tr("All buttons reset to normal state"));
168+
});
163169

164170
// 按钮状态变化信号
165-
auto updateStatus = [=](const QString &name, bool checked) {
171+
auto updateStatus = [statusLabel](const QString &name, bool checked) {
166172
QString state = checked ? tr("checked") : tr("unchecked");
167173
statusLabel->setText(tr("%1 is %2").arg(name).arg(state));
168174
};
169175

170-
connect(button1, &QPushButton::toggled, this, [=](bool checked) {
176+
connect(button1, &QPushButton::toggled, this, [updateStatus](bool checked) {
171177
updateStatus(tr("Normal PushButton"), checked);
172178
});
173179

174-
connect(button2, &QToolButton::toggled, this, [=](bool checked) {
180+
connect(button2, &QToolButton::toggled, this, [updateStatus](bool checked) {
175181
updateStatus(tr("Tool Button"), checked);
176182
});
177183

178-
connect(button3, &QPushButton::toggled, this, [=](bool checked) {
184+
connect(button3, &QPushButton::toggled, this, [updateStatus](bool checked) {
179185
updateStatus(tr("Icon Button"), checked);
180186
});
181187

182-
connect(button4, &QPushButton::toggled, this, [=](bool checked) {
188+
connect(button4, &QPushButton::toggled, this, [updateStatus](bool checked) {
183189
updateStatus(tr("Radio Style Button 1"), checked);
184190
});
185191

186-
connect(button5, &QPushButton::toggled, this, [=](bool checked) {
192+
connect(button5, &QPushButton::toggled, this, [updateStatus](bool checked) {
187193
updateStatus(tr("Radio Style Button 2"), checked);
188194
});
189195

190196
// 鼠标进入/离开事件的状态显示
191-
auto installHoverHandler = [=](QWidget *widget, const QString &name) {
197+
auto installHoverHandler = [statusLabel](QWidget *widget, const QString &name) {
192198
widget->installEventFilter(new HoverEventFilter(widget, name, statusLabel));
193199
};
194200

src/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ add_subdirectory(GridViewModel)
1212
add_subdirectory(HttpClient)
1313
add_subdirectory(LifecycleCallback)
1414
add_subdirectory(LoadingIndicator)
15-
add_subdirectory(LogAsynchronous)
1615
add_subdirectory(MulClient)
1716
add_subdirectory(MulServer)
1817
add_subdirectory(NavigationProgressBar)

src/CheckableTreeItem/mainwindow.cc

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,14 @@ void buildFileSystemTreeImpl(QStandardItemModel *model,
2323
// 使用单次定时器延迟构建,确保UI先显示
2424
QMetaObject::invokeMethod(
2525
qApp,
26-
[=]() {
26+
[model,
27+
treeView,
28+
progressBar,
29+
statusLabel,
30+
countLabel,
31+
loadingLabel,
32+
countTreeItems,
33+
countCheckedItems]() {
2734
loadingLabel->setText("Building root directory...");
2835

2936
// 获取根目录路径(跨平台)
@@ -249,7 +256,15 @@ MainWindow::MainWindow(QWidget *parent)
249256
};
250257

251258
// 构建文件系统树的函数
252-
auto buildFileSystemTree = [=]() {
259+
auto buildFileSystemTree = [model,
260+
treeView,
261+
progressBar,
262+
statusLabel,
263+
countLabel,
264+
mainLayout,
265+
centralWidget,
266+
countTreeItems,
267+
countCheckedItems]() {
253268
return buildFileSystemTreeImpl(model,
254269
treeView,
255270
progressBar,
@@ -288,20 +303,25 @@ MainWindow::MainWindow(QWidget *parent)
288303
countLabel->setText("Checked Items: 0");
289304
});
290305

291-
connect(expandAllBtn, &QPushButton::clicked, [treeView]() { treeView->expandAll(); });
306+
connect(expandAllBtn, &QPushButton::clicked, this, [treeView]() { treeView->expandAll(); });
292307

293-
connect(collapseAllBtn, &QPushButton::clicked, [treeView]() { treeView->collapseAll(); });
308+
connect(collapseAllBtn, &QPushButton::clicked, this, [treeView]() { treeView->collapseAll(); });
294309

295-
connect(refreshBtn, &QPushButton::clicked, [=]() { buildFileSystemTree(); });
310+
connect(refreshBtn, &QPushButton::clicked, this, [buildFileSystemTree]() {
311+
buildFileSystemTree();
312+
});
296313

297314
// 连接模型数据变化信号来更新计数
298-
connect(model, &QStandardItemModel::itemChanged, [=](QStandardItem *item) {
299-
Q_UNUSED(item)
300-
if (model->rowCount() > 0) {
301-
int checkedCount = countCheckedItems(model->item(0));
302-
countLabel->setText(QString("Checked Items: %1").arg(checkedCount));
303-
}
304-
});
315+
connect(model,
316+
&QStandardItemModel::itemChanged,
317+
this,
318+
[model, countLabel, countCheckedItems](QStandardItem *item) {
319+
Q_UNUSED(item)
320+
if (model->rowCount() > 0) {
321+
int checkedCount = countCheckedItems(model->item(0));
322+
countLabel->setText(QString("Checked Items: %1").arg(checkedCount));
323+
}
324+
});
305325
}
306326

307327
MainWindow::~MainWindow() {}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
set(PROJECT_SOURCES loadingindicator.cc loadingindicator.hpp main.cc
22
mainwindow.cc mainwindow.hpp)
33

4-
qt_add_resources(SOURCES resource.qrc)
4+
qt_add_resources(SOURCES resources.qrc)
55

66
qt_add_executable(LoadingIndicator ${PROJECT_SOURCES} ${SOURCES})
77
target_link_libraries(LoadingIndicator PRIVATE Qt::Widgets)

src/LoadingIndicator/LoadingIndicator.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ HEADERS += \
1414
mainwindow.hpp
1515

1616
RESOURCES += \
17-
resource.qrc
17+
resources.qrc
1818

1919
DESTDIR = $$RUNTIME_OUTPUT_DIRECTORY
2020

13.7 KB
Loading

0 commit comments

Comments
 (0)