Skip to content

Commit 3892565

Browse files
committed
[重构加载指示器组件并优化UI代码]: 全面重构LoadingIndicator组件,新增QtQuick版本加载指示器,统一颜色选择控件实现,提升代码质量和用户体验
- **加载指示器组件重构**: 完全重写LoadingIndicator组件,支持四种动画样式(旋转点、脉冲圆、跳动条、自定义GIF),增加文本显示、颜色自定义、覆盖层模式等高级功能 - **新增QtQuick组件**: 添加LoadingIndicatorQuick和LoadingOverlayQuick两个QML组件,为现代QtQuick应用提供原生加载指示解决方案 - **UI代码统一优化**: 重构Battery、Bubble、Clock、DashBoard等组件的颜色选择控件,采用统一的颜色预览按钮设计,显示颜色值和实时预览,提升界面一致性 - **项目结构调整**: 移除旧的LogAsynchronous模块,在CMakeLists.txt中添加新的QtQuick组件,更新资源文件命名和引用路径 - **文档完善更新**: 全面更新README.md文档,详细描述新增组件的特性和使用方法,替换示例图片,提供更完整的组件说明 - **代码质量提升**: 修复多个组件的lambda表达式捕获问题,改进信号槽连接方式,增强代码的稳定性和可维护性
1 parent 633dd84 commit 3892565

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2092
-881
lines changed

README.md

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -104,40 +104,43 @@
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+
- <img src="src/LoadingIndicator/images/loading.png" width="450" alt="加载指示器截图">
115+
116+
### [LoadingIndicatorQuick](src/LoadingIndicatorQuick/) - 加载指示器控件 (QtQuick版本)
117+
118+
- 基于QtQuick 2的现代化加载指示器组件
119+
- 支持四种动画样式:旋转圆点、脉冲圆圈、跳动条形、GIF动画
120+
- 完全声明式API,易于在QML中使用
121+
- 内置覆盖层功能,可轻松实现全屏加载效果
122+
- 响应式设计,自动适应容器尺寸
123+
- 支持实时属性绑定和动画控制
124+
- <img src="src/LoadingIndicatorQuick/images/loading.png" width="450" alt="QML加载指示器截图">
125+
126+
### [LoadingOverlayQuick](src/LoadingOverlayQuick/) - 加载覆盖层控件 (QtQuick版本)
127+
128+
- 基于QtQuick Popup的轻量级加载覆盖层组件
129+
- 使用系统原生BusyIndicator,确保平台一致性
130+
- 模态对话框设计,阻止用户交互
131+
- 支持动态文本设置和颜色自定义
132+
- 简洁API,提供show/hide方法控制显示
133+
- 自动居中显示,适配不同屏幕尺寸
134+
- <img src="src/LoadingOverlayQuick/images/loading.png" width="350" alt="加载覆盖层截图">
135+
136+
### [LogAsync](https://github.com/RealChuan/Qt-App/blob/main/src/utils/logasync.h) - 异步日志记录系统
137+
138+
- 独立线程处理日志写入,避免阻塞主线程
139+
- 支持控制台输出、文件记录或两者同时输出
140+
- 按大小和时间自动滚动日志文件,支持自动清理旧文件
141+
- 可设置不同日志级别(Debug、Info、Warning、Error、Fatal)
142+
- 控制台输出长度限制,避免过长日志刷屏
143+
- 内置信号槽机制,确保多线程环境下的数据安全
141144

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

src/Battery/images/battery.png

1.01 KB
Loading

src/Battery/mainwindow.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,8 @@ MainWindow::MainWindow(QWidget *parent)
2626
auto *alarmLabel = new QLabel(tr("Alarm threshold: 20%"), this);
2727

2828
// 创建颜色选择控件 - 使用颜色预览按钮
29-
auto *powerColorLabel = new QLabel(tr("Battery color:"), this);
3029
auto *powerColorButton = new QPushButton(this);
31-
32-
auto *alarmColorLabel = new QLabel(tr("Alarm color:"), this);
3330
auto *alarmColorButton = new QPushButton(this);
34-
35-
auto *borderColorLabel = new QLabel(tr("Border color:"), this);
3631
auto *borderColorButton = new QPushButton(this);
3732

3833
// 创建动画控制
@@ -65,11 +60,11 @@ MainWindow::MainWindow(QWidget *parent)
6560
auto *gridLayout = new QGridLayout;
6661
gridLayout->addWidget(chargingCheckbox, 0, 0);
6762
gridLayout->addWidget(animationCheckbox, 0, 1);
68-
gridLayout->addWidget(powerColorLabel, 1, 0);
63+
gridLayout->addWidget(new QLabel(tr("Battery color:"), this), 1, 0);
6964
gridLayout->addWidget(powerColorButton, 1, 1);
70-
gridLayout->addWidget(alarmColorLabel, 2, 0);
65+
gridLayout->addWidget(new QLabel(tr("Alarm color:"), this), 2, 0);
7166
gridLayout->addWidget(alarmColorButton, 2, 1);
72-
gridLayout->addWidget(borderColorLabel, 3, 0);
67+
gridLayout->addWidget(new QLabel(tr("Border color:"), this), 3, 0);
7368
gridLayout->addWidget(borderColorButton, 3, 1);
7469
gridLayout->addWidget(alarmLabel, 4, 0);
7570
gridLayout->addWidget(alarmSlider, 4, 1);
@@ -123,8 +118,10 @@ MainWindow::MainWindow(QWidget *parent)
123118

124119
// 颜色选择 - 更新按钮颜色预览
125120
auto updateColorButton = [](QPushButton *button, const QColor &color) {
121+
auto colorName = color.name(QColor::HexArgb).toUpper();
126122
button->setStyleSheet(
127-
QString("background-color: %1; border: 1px solid gray;").arg(color.name()));
123+
QString("background-color: %1; border: 1px solid gray;").arg(colorName));
124+
button->setText(colorName);
128125
};
129126

130127
updateColorButton(powerColorButton, battery->powerColor());

src/BatteryQuick/Main.qml

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import QtQuick.Dialogs
55
import QtQuick.Controls.Fusion
66

77
ApplicationWindow {
8-
id: root
8+
id: mainWindow
99

1010
width: 320
1111
height: 370
@@ -91,12 +91,12 @@ ApplicationWindow {
9191
Button {
9292
id: powerColorButton
9393
Layout.fillWidth: true
94+
text: battery.powerColor.toString().toUpperCase()
9495
onClicked: {
9596
colorDialog.selectedColor = battery.powerColor;
9697
colorDialog.accepted.connect(function () {
9798
if (colorDialog.selectedColor) {
9899
battery.powerColor = colorDialog.selectedColor;
99-
updateColorButton(powerColorButton, colorDialog.selectedColor);
100100
}
101101
colorDialog.accepted.disconnect(arguments.callee);
102102
});
@@ -108,8 +108,6 @@ ApplicationWindow {
108108
border.color: "gray"
109109
border.width: 1
110110
}
111-
112-
contentItem: Item {} // 隐藏默认文本
113111
}
114112

115113
// 第三行:报警颜色选择
@@ -120,12 +118,12 @@ ApplicationWindow {
120118
Button {
121119
id: alarmColorButton
122120
Layout.fillWidth: true
121+
text: battery.alarmColor.toString().toUpperCase()
123122
onClicked: {
124123
colorDialog.selectedColor = battery.alarmColor;
125124
colorDialog.accepted.connect(function () {
126125
if (colorDialog.selectedColor) {
127126
battery.alarmColor = colorDialog.selectedColor;
128-
updateColorButton(alarmColorButton, colorDialog.selectedColor);
129127
}
130128
colorDialog.accepted.disconnect(arguments.callee);
131129
});
@@ -137,8 +135,6 @@ ApplicationWindow {
137135
border.color: "gray"
138136
border.width: 1
139137
}
140-
141-
contentItem: Item {} // 隐藏默认文本
142138
}
143139

144140
// 第四行:边框颜色选择
@@ -149,12 +145,12 @@ ApplicationWindow {
149145
Button {
150146
id: borderColorButton
151147
Layout.fillWidth: true
148+
text: battery.borderColor.toString().toUpperCase()
152149
onClicked: {
153150
colorDialog.selectedColor = battery.borderColor;
154151
colorDialog.accepted.connect(function () {
155152
if (colorDialog.selectedColor) {
156153
battery.borderColor = colorDialog.selectedColor;
157-
updateColorButton(borderColorButton, colorDialog.selectedColor);
158154
}
159155
colorDialog.accepted.disconnect(arguments.callee);
160156
});
@@ -166,8 +162,6 @@ ApplicationWindow {
166162
border.color: "gray"
167163
border.width: 1
168164
}
169-
170-
contentItem: Item {} // 隐藏默认文本
171165
}
172166

173167
// 第五行:报警阈值
@@ -240,11 +234,6 @@ ApplicationWindow {
240234
}
241235
}
242236

243-
// 更新颜色按钮预览的函数
244-
function updateColorButton(button, color) {
245-
// 颜色已经在background中自动更新,因为绑定了电池的颜色属性
246-
}
247-
248237
// 连接电池信号
249238
Connections {
250239
target: battery
-4.59 KB
Loading

src/Bubble/images/bubble.png

2.23 KB
Loading

src/Bubble/mainwindow.cpp

Lines changed: 64 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -50,24 +50,10 @@ MainWindow::MainWindow(QWidget *parent)
5050
textMarginSlider->setRange(0, 30);
5151
textMarginSlider->setValue(8);
5252

53-
// 颜色选择
54-
auto *penColorButton = new QPushButton(tr("Border Color"), this);
55-
auto *penColorLabel = new QLabel(this);
56-
penColorLabel->setFixedSize(30, 25);
57-
penColorLabel->setStyleSheet(
58-
QString("background-color: %1; border: 1px solid gray;").arg(bubble->pen().color().name()));
59-
60-
auto *brushColorButton = new QPushButton(tr("Background Color"), this);
61-
auto *brushColorLabel = new QLabel(this);
62-
brushColorLabel->setFixedSize(30, 25);
63-
brushColorLabel->setStyleSheet(QString("background-color: %1; border: 1px solid gray;")
64-
.arg(bubble->brush().color().name()));
65-
66-
auto *textColorButton = new QPushButton(tr("Text Color"), this);
67-
auto *textColorLabel = new QLabel(this);
68-
textColorLabel->setFixedSize(30, 25);
69-
textColorLabel->setStyleSheet(
70-
QString("background-color: %1; border: 1px solid gray;").arg(bubble->textColor().name()));
53+
// 颜色选择 - 使用颜色预览按钮(类似第一个代码的风格)
54+
auto *penColorButton = new QPushButton(this);
55+
auto *brushColorButton = new QPushButton(this);
56+
auto *textColorButton = new QPushButton(this);
7157

7258
// 动画控制
7359
auto *animationCheckbox = new QCheckBox(tr("Enable Animation"), this);
@@ -131,14 +117,14 @@ MainWindow::MainWindow(QWidget *parent)
131117
styleLayout->addWidget(textMarginSlider, 1, 1);
132118
styleLayout->addWidget(textMarginLabel, 1, 2);
133119

134-
styleLayout->addWidget(penColorButton, 0, 3);
135-
styleLayout->addWidget(penColorLabel, 0, 4);
120+
styleLayout->addWidget(new QLabel(tr("Border Color:"), this), 2, 0);
121+
styleLayout->addWidget(penColorButton, 2, 1, 1, 2);
136122

137-
styleLayout->addWidget(brushColorButton, 1, 3);
138-
styleLayout->addWidget(brushColorLabel, 1, 4);
123+
styleLayout->addWidget(new QLabel(tr("Background Color:"), this), 3, 0);
124+
styleLayout->addWidget(brushColorButton, 3, 1, 1, 2);
139125

140-
styleLayout->addWidget(textColorButton, 2, 3);
141-
styleLayout->addWidget(textColorLabel, 2, 4);
126+
styleLayout->addWidget(new QLabel(tr("Text Color:"), this), 4, 0);
127+
styleLayout->addWidget(textColorButton, 4, 1, 1, 2);
142128

143129
// 动画设置
144130
auto *animationLayout = new QHBoxLayout();
@@ -164,8 +150,8 @@ MainWindow::MainWindow(QWidget *parent)
164150
mainLayout->addStretch();
165151

166152
setCentralWidget(mainWidget);
167-
resize(450, 280);
168-
setWindowTitle(tr("Bubble Widget Demo"));
153+
resize(700, 430);
154+
setWindowTitle(tr("Bubble Widget Example"));
169155

170156
// ========== 信号连接 ==========
171157

@@ -205,46 +191,62 @@ MainWindow::MainWindow(QWidget *parent)
205191
bubble->setTextMargin(value);
206192
});
207193

208-
// 颜色控制连接
209-
auto createColorDialog = [this](const QString &title,
210-
const QColor &currentColor,
211-
auto setterFunc,
212-
QLabel *colorLabel) {
213-
QColor color = QColorDialog::getColor(currentColor, this, title);
214-
if (color.isValid()) {
215-
setterFunc(color);
216-
colorLabel->setStyleSheet(
217-
QString("background-color: %1; border: 1px solid gray;").arg(color.name()));
218-
}
194+
// 颜色控制连接 - 改造为类似第一个代码的风格
195+
auto updateColorButton = [](QPushButton *button, const QColor &color) {
196+
auto colorName = color.name(QColor::HexArgb).toUpper();
197+
button->setStyleSheet(
198+
QString("background-color: %1; border: 1px solid gray;").arg(colorName));
199+
button->setText(colorName);
219200
};
220201

221-
connect(penColorButton, &QPushButton::clicked, [bubble, penColorLabel, createColorDialog]() {
222-
createColorDialog(
223-
tr("Select Border Color"),
224-
bubble->pen().color(),
225-
[bubble](const QColor &color) {
226-
QPen pen = bubble->pen();
227-
pen.setColor(color);
228-
bubble->setPen(pen);
229-
},
230-
penColorLabel);
231-
});
202+
// 初始化颜色按钮
203+
updateColorButton(penColorButton, bubble->pen().color());
204+
updateColorButton(brushColorButton, bubble->brush().color());
205+
updateColorButton(textColorButton, bubble->textColor());
232206

233-
connect(brushColorButton, &QPushButton::clicked, [bubble, brushColorLabel, createColorDialog]() {
234-
createColorDialog(
235-
tr("Select Background Color"),
236-
bubble->brush().color(),
237-
[bubble](const QColor &color) { bubble->setBrush(QBrush(color)); },
238-
brushColorLabel);
239-
});
207+
// 边框颜色选择
208+
connect(penColorButton,
209+
&QPushButton::clicked,
210+
this,
211+
[this, bubble, penColorButton, updateColorButton]() {
212+
QColor color = QColorDialog::getColor(bubble->pen().color(),
213+
this,
214+
tr("Select Border Color"));
215+
if (color.isValid()) {
216+
QPen pen = bubble->pen();
217+
pen.setColor(color);
218+
bubble->setPen(pen);
219+
updateColorButton(penColorButton, color);
220+
}
221+
});
240222

241-
connect(textColorButton, &QPushButton::clicked, [bubble, textColorLabel, createColorDialog]() {
242-
createColorDialog(
243-
tr("Select Text Color"),
244-
bubble->textColor(),
245-
[bubble](const QColor &color) { bubble->setTextColor(color); },
246-
textColorLabel);
247-
});
223+
// 背景颜色选择
224+
connect(brushColorButton,
225+
&QPushButton::clicked,
226+
this,
227+
[this, bubble, brushColorButton, updateColorButton]() {
228+
QColor color = QColorDialog::getColor(bubble->brush().color(),
229+
this,
230+
tr("Select Background Color"));
231+
if (color.isValid()) {
232+
bubble->setBrush(QBrush(color));
233+
updateColorButton(brushColorButton, color);
234+
}
235+
});
236+
237+
// 文本颜色选择
238+
connect(textColorButton,
239+
&QPushButton::clicked,
240+
this,
241+
[this, bubble, textColorButton, updateColorButton]() {
242+
QColor color = QColorDialog::getColor(bubble->textColor(),
243+
this,
244+
tr("Select Text Color"));
245+
if (color.isValid()) {
246+
bubble->setTextColor(color);
247+
updateColorButton(textColorButton, color);
248+
}
249+
});
248250

249251
// 动画控制连接
250252
connect(animationDurationSlider,

0 commit comments

Comments
 (0)