Skip to content

Commit ea7c7e0

Browse files
committed
chore: release v0.1.6
1 parent e1019b1 commit ea7c7e0

9 files changed

Lines changed: 101 additions & 15 deletions

File tree

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,20 @@
22

33
本项目遵循面向用户的变更记录格式。版本号在正式发布前可能继续调整。
44

5+
## [0.1.6] - 2026-07-08
6+
7+
### 新增
8+
9+
- 接收显示和文本发送支持分别选择 UTF-8、GBK、ASCII、Latin1 编码,并持久化保存配置。
10+
- 增加校验工具,支持 CRC16-Modbus、CRC16-CCITT、CRC32、LRC、XOR、SUM8 手动计算、大小端显示和发送时自动追加。
11+
- 自动断帧增强为支持按接收间隔、固定帧头、固定帧尾和固定长度断帧。
12+
- 增加 Modbus RTU 辅助,支持常用读写请求帧生成、CRC16-Modbus 自动追加、填入发送区、直接发送和响应摘要解析。
13+
- 左侧连接、接收设置、发送设置、Modbus RTU、常用包和文件发送卡片支持折叠,并记住每张卡片的折叠状态。
14+
15+
### 修复
16+
17+
- 修复常用包和文件发送卡片折叠后仍残留内容区空白高度的问题。
18+
519
## [0.1.5] - 2026-07-08
620

721
### 新增

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.21)
22

33
project(
44
FluentSerialAssistant
5-
VERSION 0.1.5
5+
VERSION 0.1.6
66
DESCRIPTION "A Fluent Qt serial assistant prototype"
77
LANGUAGES CXX
88
)

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Fluent 串口助手是一个基于 C++17、Qt 6 Widgets 和 FluentQtWidgets 的
3535
- 数据发送:支持文本和 HEX 发送,支持 None、CR、LF、CRLF 行结束符。
3636
- 校验工具:支持 CRC16-Modbus、CRC16-CCITT、CRC32、LRC、XOR、SUM8 手动计算和发送时自动追加。
3737
- Modbus RTU:支持常用读写请求帧生成、CRC 自动追加、直接发送和响应摘要解析。
38+
- 左侧卡片:连接、接收、发送、Modbus、常用包和文件发送卡片可折叠,并记住折叠状态。
3839
- 发送历史:保留最近 20 条唯一发送记录。
3940
- 常用包:支持保存、载入、发送、删除和排序常用发送包。
4041
- 循环发送:支持毫秒级发送间隔。
@@ -193,8 +194,9 @@ dist/FluentSerialAssistant-release
193194
5. 在发送区输入文本或 HEX 数据,必要时选择收发编码、行结束符和校验自动追加后发送。
194195
6. 可在常用包中填写名称、内容、模式和换行后保存,之后选中条目即可填入发送区或直接发送。
195196
7. 可选择文件,配置块大小和间隔后分块发送。
196-
8. 可开启自动断帧、时间戳、自动滚动、循环发送等选项。
197-
9. 使用 TXT、CSV、BIN 导出会话记录。
197+
8. 可点击左侧卡片标题折叠不常用配置,减少侧栏占用。
198+
9. 可开启自动断帧、时间戳、自动滚动、循环发送等选项。
199+
10. 使用 TXT、CSV、BIN 导出会话记录。
198200

199201
## 许可证
200202

docs/feature-roadmap.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
- 串口扫描:端口名、描述、厂商、VID/PID、序列号。
88
- 连接参数:波特率、数据位、校验位、停止位、流控、RTS、DTR。
99
- 连接体验:手动刷新、自动重连、启动后自动连接上次串口。
10-
- 接收显示:文本、HEX、混合显示、时间戳、自动断帧、暂停显示、自动滚动、清空记录。
10+
- 接收显示:文本、HEX、混合显示、接收编码选择、时间戳、自动断帧、暂停显示、自动滚动、清空记录。
1111
- 终端检索:关键字搜索,以及全部、接收、发送方向过滤。
1212
- 状态统计:RX/TX 总量、实时速率、连接时长、计数重置。
13-
- 数据发送:文本/HEX 发送,None/CR/LF/CRLF 行结束符。
13+
- 数据发送:文本/HEX 发送、发送编码选择、None/CR/LF/CRLF 行结束符、校验码自动追加。
14+
- 校验工具:CRC16-Modbus、CRC16-CCITT、CRC32、LRC、XOR、SUM8。
15+
- Modbus RTU:常用读写请求帧生成、CRC 自动追加、直接发送和响应摘要解析。
1416
- 发送历史:保存最近发送内容并可回填。
1517
- 常用包:保存、载入、发送、删除、排序。
1618
- 定时发送:按毫秒级间隔循环发送当前内容。
@@ -19,6 +21,7 @@
1921
- 接收保存:将接收原始数据保存到文件。
2022
- 会话恢复:恢复串口参数、发送输入、常用包、文件发送参数。
2123
- 外观设置:浅色、深色、跟随系统、主题色、界面字体和终端字体。
24+
- 布局体验:左侧连接、接收、发送、Modbus、常用包和文件发送卡片可折叠,并记住折叠状态。
2225

2326
## P0:优先增强
2427

docs/release-notes/v0.1.6.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Fluent 串口助手 v0.1.6
2+
3+
这是一个协议调试能力和左侧布局体验增强版本。
4+
5+
## 新增
6+
7+
- 接收显示和文本发送支持分别选择 UTF-8、GBK、ASCII、Latin1 编码。
8+
- 增加校验工具,支持 CRC16-Modbus、CRC16-CCITT、CRC32、LRC、XOR、SUM8 计算。
9+
- 支持校验结果大小端显示,并可在发送时自动追加校验码。
10+
- 自动断帧支持按接收间隔、固定帧头、固定帧尾和固定长度断帧。
11+
- 增加 Modbus RTU 辅助,可生成常用读写请求帧、自动追加 CRC、填入发送区或直接发送。
12+
- Modbus RTU 响应支持基础摘要解析,包括站号、功能码、数据、异常码和 CRC 状态。
13+
- 左侧功能卡片支持折叠,并记住每张卡片的折叠状态。
14+
15+
## 修复
16+
17+
- 修复常用包和文件发送卡片折叠后仍残留内容区空白高度的问题。
18+
19+
## 验证
20+
21+
- `cmake --build build/codex-release --target format-check`
22+
- `cmake --build build/codex-release --parallel`

src/app/view/workbench/workbench_page_internal.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include <QtCore/QSettings>
2424
#include <QtCore/QSignalBlocker>
2525
#include <QtCore/QStandardPaths>
26+
#include <QtCore/QTimer>
27+
#include <QtCore/QVariant>
2628
#include <QtGui/QIcon>
2729
#include <QtGui/QKeyEvent>
2830
#include <QtGui/QTextCharFormat>
@@ -144,6 +146,34 @@ inline void hideCardTitle(HeaderCardWidget *card)
144146
}
145147
}
146148

149+
inline void normalizeCollapsedCardHeight(ExpandSettingCard *card)
150+
{
151+
if (!card || card->isExpanded() || !card->card()) {
152+
return;
153+
}
154+
155+
card->setFixedHeight(card->card()->height());
156+
card->updateGeometry();
157+
}
158+
159+
inline void makeCollapsibleCard(ExpandSettingCard *card, const QString &settingsName)
160+
{
161+
if (!card) {
162+
return;
163+
}
164+
165+
const QString key = QStringLiteral("workbench/leftCards/%1Collapsed").arg(settingsName);
166+
card->setExpanded(!QSettings().value(key, false).toBool());
167+
normalizeCollapsedCardHeight(card);
168+
QObject::connect(card, &ExpandSettingCard::expandedChanged, card, [card, key](bool expanded) {
169+
QSettings settings;
170+
settings.setValue(key, !expanded);
171+
if (!expanded) {
172+
QTimer::singleShot(240, card, [card]() { normalizeCollapsedCardHeight(card); });
173+
}
174+
});
175+
}
176+
147177
inline QVBoxLayout *cardBody(HeaderCardWidget *card, int margin = 12)
148178
{
149179
card->setBorderRadius(8);
@@ -158,6 +188,18 @@ inline QVBoxLayout *cardBody(HeaderCardWidget *card, int margin = 12)
158188
return layout;
159189
}
160190

191+
inline QVBoxLayout *cardBody(ExpandSettingCard *card, int margin = 12)
192+
{
193+
card->viewLayout()->setContentsMargins(0, 0, 0, 0);
194+
195+
auto *body = new QWidget(card->view());
196+
auto *layout = new QVBoxLayout(body);
197+
layout->setContentsMargins(margin, margin, margin, margin);
198+
layout->setSpacing(8);
199+
card->viewLayout()->addWidget(body);
200+
return layout;
201+
}
202+
161203
inline void makeCompactControl(QWidget *control)
162204
{
163205
control->setMinimumWidth(0);

src/app/view/workbench/workbench_page_modbus.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ using namespace WorkbenchPagePrivate;
55

66
QWidget *WorkbenchPage::createModbusSection()
77
{
8-
auto *section = new HeaderCardWidget(QStringLiteral("Modbus RTU"), this);
8+
auto *section = new ExpandSettingCard(FluentIcon::CommandPrompt, QStringLiteral("Modbus RTU"), QString(), this);
99
auto *root = cardBody(section);
1010

1111
m_modbusSlaveSpin = new SpinBox(section);
@@ -80,6 +80,7 @@ QWidget *WorkbenchPage::createModbusSection()
8080
connect(m_modbusSendButton, &PrimaryPushButton::clicked, this, &WorkbenchPage::sendModbusRequest);
8181

8282
updateModbusUi();
83+
makeCollapsibleCard(section, QStringLiteral("modbus"));
8384
return section;
8485
}
8586

src/app/view/workbench/workbench_page_side_sections.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ using namespace WorkbenchPagePrivate;
55

66
QWidget *WorkbenchPage::createConnectionSection()
77
{
8-
auto *section = new HeaderCardWidget(this);
9-
hideCardHeader(section);
8+
auto *section = new ExpandSettingCard(FluentIcon::Connect, QStringLiteral("连接"), QString(), this);
109
auto *root = cardBody(section);
1110

1211
m_portCombo = new ComboBox(section);
@@ -79,13 +78,13 @@ QWidget *WorkbenchPage::createConnectionSection()
7978
settings.setValue(QStringLiteral("serial/autoOpen"), checked);
8079
});
8180

81+
makeCollapsibleCard(section, QStringLiteral("connection"));
8282
return section;
8383
}
8484

8585
QWidget *WorkbenchPage::createReceiveSettingsSection()
8686
{
87-
auto *section = new HeaderCardWidget(this);
88-
hideCardHeader(section);
87+
auto *section = new ExpandSettingCard(FluentIcon::Download, QStringLiteral("接收设置"), QString(), this);
8988
auto *root = cardBody(section);
9089

9190
m_displayModeSegment = new SegmentedWidget(section);
@@ -251,13 +250,13 @@ QWidget *WorkbenchPage::createReceiveSettingsSection()
251250
connect(m_exportCsvButton, &PushButton::clicked, this, [this]() { exportRecords(ExportFormat::Csv); });
252251
connect(m_exportBinButton, &PushButton::clicked, this, [this]() { exportRecords(ExportFormat::Bin); });
253252

253+
makeCollapsibleCard(section, QStringLiteral("receive"));
254254
return section;
255255
}
256256

257257
QWidget *WorkbenchPage::createSendSettingsSection()
258258
{
259-
auto *section = new HeaderCardWidget(this);
260-
hideCardHeader(section);
259+
auto *section = new ExpandSettingCard(FluentIcon::Send, QStringLiteral("发送设置"), QString(), this);
261260
auto *root = cardBody(section);
262261

263262
m_lineEndingCombo = new ComboBox(section);
@@ -373,12 +372,13 @@ QWidget *WorkbenchPage::createSendSettingsSection()
373372
}
374373
});
375374

375+
makeCollapsibleCard(section, QStringLiteral("send"));
376376
return section;
377377
}
378378

379379
QWidget *WorkbenchPage::createPacketSection()
380380
{
381-
auto *section = new HeaderCardWidget(QStringLiteral("常用包"), this);
381+
auto *section = new ExpandSettingCard(FluentIcon::Library, QStringLiteral("常用包"), QString(), this);
382382
auto *root = cardBody(section);
383383

384384
m_packetNameEdit = new LineEdit(section);
@@ -459,12 +459,13 @@ QWidget *WorkbenchPage::createPacketSection()
459459
connect(m_packetDownButton, &ToolButton::clicked, this, [this]() { moveSelectedPacket(1); });
460460

461461
updatePacketTable();
462+
makeCollapsibleCard(section, QStringLiteral("packets"));
462463
return section;
463464
}
464465

465466
QWidget *WorkbenchPage::createFileSendSection()
466467
{
467-
auto *section = new HeaderCardWidget(QStringLiteral("文件发送"), this);
468+
auto *section = new ExpandSettingCard(FluentIcon::Folder, QStringLiteral("文件发送"), QString(), this);
468469
auto *root = cardBody(section);
469470

470471
m_filePathEdit = new LineEdit(section);
@@ -513,5 +514,6 @@ QWidget *WorkbenchPage::createFileSendSection()
513514
connect(m_fileCancelButton, &PushButton::clicked, this, &WorkbenchPage::cancelFileSend);
514515

515516
updateFileSendUi(false);
517+
makeCollapsibleCard(section, QStringLiteral("fileSend"));
516518
return section;
517519
}

src/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ int main(int argc, char *argv[])
2020
app.setStyle(QStyleFactory::create(QStringLiteral("Fusion")));
2121
QCoreApplication::setOrganizationName(QStringLiteral("txp"));
2222
QCoreApplication::setApplicationName(QStringLiteral("FluentSerialAssistant"));
23-
QCoreApplication::setApplicationVersion(QStringLiteral("0.1.5"));
23+
QCoreApplication::setApplicationVersion(QStringLiteral("0.1.6"));
2424

2525
AppFontPreferences::loadCustomFonts();
2626
FluentQt::FluentConfig::instance()->load();

0 commit comments

Comments
 (0)