优化文本输出和优化渲染

This commit is contained in:
JackLee 2025-03-02 19:52:03 +08:00
parent 41a78331fe
commit 27701be2e3
15 changed files with 4178 additions and 4161 deletions

Binary file not shown.

View File

@ -1,75 +1,63 @@
# ninja log v6 # ninja log v6
4748 8878 7626095344479039 CMakeFiles/ctai.dir/src/sui_sys_style.cpp.obj e3d97ea8bc1d2b2c 4748 8878 7626095344479039 CMakeFiles/ctai.dir/src/sui_sys_style.cpp.obj e3d97ea8bc1d2b2c
302 529 7626054468283748 F:/SourceCode/ctai/build/qrc_res.cpp 9794859fafc6825 282 1037 7626126587503169 F:/SourceCode/ctai/build/qrc_res.cpp 9794859fafc6825
20 312 7626110238955525 ctai_autogen/timestamp da3870ebc94b983e 18 4707 7626178974330825 ctai_autogen/timestamp da3870ebc94b983e
313 18539 7626110241890638 CMakeFiles/ctai.dir/src/ctai_curl.cpp.obj 511f74c0fcaa2e5f 4716 27348 7626171843740194 CMakeFiles/ctai.dir/src/ctai_curl.cpp.obj 511f74c0fcaa2e5f
7092 13031 7624392729099354 CMakeFiles/ctai.dir/src/ctai_session_docker.cpp.obj 215fc89727d9e8c1 7092 13031 7624392729099354 CMakeFiles/ctai.dir/src/ctai_session_docker.cpp.obj 215fc89727d9e8c1
4864 36817 7625506355308043 CMakeFiles/ctai.dir/src/ctai_textedit.cpp.obj 10751092db60a69f 4864 36817 7625506355308043 CMakeFiles/ctai.dir/src/ctai_textedit.cpp.obj 10751092db60a69f
4976 42558 7626100271278798 CMakeFiles/ctai.dir/src/ctai_tabwidget.cpp.obj 30e97d05c008cea2 4719 39095 7626178975475971 CMakeFiles/ctai.dir/src/ctai_tabwidget.cpp.obj 30e97d05c008cea2
4967 37911 7626100271193199 CMakeFiles/ctai.dir/src/ctai_history_widget.cpp.obj ff767b1a439cfa8f 4713 35554 7626178975415913 CMakeFiles/ctai.dir/src/ctai_history_widget.cpp.obj ff767b1a439cfa8f
4753 10111 7626095344533870 CMakeFiles/ctai.dir/qrc_res.cpp.obj dd75527ee8dace65 1040 3803 7626126587682989 CMakeFiles/ctai.dir/qrc_res.cpp.obj dd75527ee8dace65
20 312 7626110238955525 F:/SourceCode/ctai/build/ctai_autogen/timestamp da3870ebc94b983e 18 4707 7626178974330825 F:/SourceCode/ctai/build/ctai_autogen/timestamp da3870ebc94b983e
4971 44642 7626100271233155 CMakeFiles/ctai.dir/src/ctai_session_info.cpp.obj d12cfe3d50990a54 4715 40361 7626178975435898 CMakeFiles/ctai.dir/src/ctai_session_info.cpp.obj d12cfe3d50990a54
6820 11551 7626094937733457 CMakeFiles/ctai.dir/src/ctai_switch_control.cpp.obj 5b4f3fa17aadf05d 6820 11551 7626094937733457 CMakeFiles/ctai.dir/src/ctai_switch_control.cpp.obj 5b4f3fa17aadf05d
4962 48705 7626100271140359 CMakeFiles/ctai.dir/src/ctai.cpp.obj f1f03f3c05222920 4710 43893 7626178975383532 CMakeFiles/ctai.dir/src/ctai.cpp.obj f1f03f3c05222920
20 312 7626110238955525 ctai_autogen/mocs_compilation.cpp da3870ebc94b983e 18 4707 7626178974330825 ctai_autogen/mocs_compilation.cpp da3870ebc94b983e
4751 18066 7626095344513825 CMakeFiles/ctai.dir/src/sui_title.cpp.obj 226322322265d1f8 4751 18066 7626095344513825 CMakeFiles/ctai.dir/src/sui_title.cpp.obj 226322322265d1f8
4973 43773 7626100271256523 CMakeFiles/ctai.dir/src/ctai_session_widget.cpp.obj 44a14cc778bf0b 4717 39808 7626178975450957 CMakeFiles/ctai.dir/src/ctai_session_widget.cpp.obj 44a14cc778bf0b
4857 36686 7625506355235589 CMakeFiles/ctai.dir/src/ctai_msg_table.cpp.obj d5f943362cb1824b 4857 36686 7625506355235589 CMakeFiles/ctai.dir/src/ctai_msg_table.cpp.obj d5f943362cb1824b
6815 11759 7626094937673639 CMakeFiles/ctai.dir/src/ctai_session_setting.cpp.obj 97bcecdc81f8d69a 6815 11759 7626094937673639 CMakeFiles/ctai.dir/src/ctai_session_setting.cpp.obj 97bcecdc81f8d69a
4969 7174 7626100271213174 CMakeFiles/ctai.dir/src/ctai_parsestring.cpp.obj e7088975ee9d75b9 4969 7174 7626100271213174 CMakeFiles/ctai.dir/src/ctai_parsestring.cpp.obj e7088975ee9d75b9
308 24704 7626106165519846 CMakeFiles/ctai.dir/src/ctai_history_textedit.cpp.obj 9afc647ddec3b160 4712 35257 7626178975395928 CMakeFiles/ctai.dir/src/ctai_history_textedit.cpp.obj 9afc647ddec3b160
6804 11907 7626094937567230 CMakeFiles/ctai.dir/src/ctai_cmd.cpp.obj f2014334430e71bd 6804 11907 7626094937567230 CMakeFiles/ctai.dir/src/ctai_cmd.cpp.obj f2014334430e71bd
6823 11650 7626094937761135 CMakeFiles/ctai.dir/src/ctai_tabbar.cpp.obj eeafbafed35daaf2 6823 11650 7626094937761135 CMakeFiles/ctai.dir/src/ctai_tabbar.cpp.obj eeafbafed35daaf2
4980 5212 7626100271326872 CMakeFiles/ctai.dir/sui.rc.obj 8caec2f89e692c3b 4980 5212 7626100271326872 CMakeFiles/ctai.dir/sui.rc.obj 8caec2f89e692c3b
4960 50397 7626100271120321 CMakeFiles/ctai.dir/ctai_autogen/mocs_compilation.cpp.obj 17adb079db0c1349 4708 46038 7626178975361596 CMakeFiles/ctai.dir/ctai_autogen/mocs_compilation.cpp.obj 17adb079db0c1349
302 529 7626054468283748 qrc_res.cpp 9794859fafc6825
4742 18062 7626095344408993 CMakeFiles/ctai.dir/src/sui.cpp.obj 42bed78c7899bffd
20 312 7626110238955525 F:/SourceCode/ctai/build/ctai_autogen/mocs_compilation.cpp da3870ebc94b983e
18539 29807 7626110424156190 F:/SourceCode/ctai/release/ctai.exe bbede5bc6dd5d74a
4745 24869 7626095344451563 CMakeFiles/ctai.dir/src/sui_base_ex.cpp.obj 4278f5aab5827fc6
4978 44360 7626100271298778 CMakeFiles/ctai.dir/src/main.cpp.obj cdab1c27daa47f87
7096 13484 7624392729149768 CMakeFiles/ctai.dir/src/ctai_session_table.cpp.obj 5bacfc2db149ebf7
18 5097 7626113129573703 ctai_autogen/timestamp da3870ebc94b983e
18 5097 7626113129573703 ctai_autogen/mocs_compilation.cpp da3870ebc94b983e
18 5097 7626113129573703 F:/SourceCode/ctai/build/ctai_autogen/timestamp da3870ebc94b983e
18 5097 7626113129573703 F:/SourceCode/ctai/build/ctai_autogen/mocs_compilation.cpp da3870ebc94b983e
5102 27531 7626113130732535 CMakeFiles/ctai.dir/src/ctai_curl.cpp.obj 511f74c0fcaa2e5f
5107 40373 7626113130794872 CMakeFiles/ctai.dir/src/ctai_tabwidget.cpp.obj 30e97d05c008cea2
5105 41606 7626113130777479 CMakeFiles/ctai.dir/src/ctai_session_widget.cpp.obj 44a14cc778bf0b
5110 41840 7626113130818153 CMakeFiles/ctai.dir/src/main.cpp.obj cdab1c27daa47f87
5104 42037 7626113130759961 CMakeFiles/ctai.dir/src/ctai_session_info.cpp.obj d12cfe3d50990a54
5100 45613 7626113130715147 CMakeFiles/ctai.dir/src/ctai.cpp.obj f1f03f3c05222920
5098 47450 7626113130697750 CMakeFiles/ctai.dir/ctai_autogen/mocs_compilation.cpp.obj 17adb079db0c1349
47451 59001 7626113554232029 F:/SourceCode/ctai/release/ctai.exe bbede5bc6dd5d74a
26 5281 7626118030849102 ctai_autogen/timestamp da3870ebc94b983e
26 5281 7626118030849102 ctai_autogen/mocs_compilation.cpp da3870ebc94b983e
26 5281 7626118030849102 F:/SourceCode/ctai/build/ctai_autogen/timestamp da3870ebc94b983e
26 5281 7626118030849102 F:/SourceCode/ctai/build/ctai_autogen/mocs_compilation.cpp da3870ebc94b983e
18 5237 7626118451724977 ctai_autogen/timestamp da3870ebc94b983e
18 5237 7626118451724977 ctai_autogen/mocs_compilation.cpp da3870ebc94b983e
18 5237 7626118451724977 F:/SourceCode/ctai/build/ctai_autogen/timestamp da3870ebc94b983e
18 5237 7626118451724977 F:/SourceCode/ctai/build/ctai_autogen/mocs_compilation.cpp da3870ebc94b983e
5242 27105 7626118452872000 CMakeFiles/ctai.dir/src/ctai_curl.cpp.obj 511f74c0fcaa2e5f
5250 39767 7626118452959188 CMakeFiles/ctai.dir/src/ctai_tabwidget.cpp.obj 30e97d05c008cea2
5248 41203 7626118452924396 CMakeFiles/ctai.dir/src/ctai_session_widget.cpp.obj 44a14cc778bf0b
5253 41395 7626118452969228 CMakeFiles/ctai.dir/src/main.cpp.obj cdab1c27daa47f87
5245 41406 7626118452907010 CMakeFiles/ctai.dir/src/ctai_session_info.cpp.obj d12cfe3d50990a54
5240 44971 7626118452856952 CMakeFiles/ctai.dir/src/ctai.cpp.obj f1f03f3c05222920
5238 46923 7626118452822166 CMakeFiles/ctai.dir/ctai_autogen/mocs_compilation.cpp.obj 17adb079db0c1349
46923 59102 7626118869689173 F:/SourceCode/ctai/release/ctai.exe bbede5bc6dd5d74a
19 296 7626124060032869 ctai_autogen/timestamp da3870ebc94b983e
19 296 7626124060032869 ctai_autogen/mocs_compilation.cpp da3870ebc94b983e
19 296 7626124060032869 F:/SourceCode/ctai/build/ctai_autogen/timestamp da3870ebc94b983e
19 296 7626124060032869 F:/SourceCode/ctai/build/ctai_autogen/mocs_compilation.cpp da3870ebc94b983e
322 18468 7626124063044093 CMakeFiles/ctai.dir/src/ctai_curl.cpp.obj 511f74c0fcaa2e5f
18469 29607 7626124244517930 F:/SourceCode/ctai/release/ctai.exe bbede5bc6dd5d74a
17 281 7626126577458232 ctai_autogen/timestamp da3870ebc94b983e
17 281 7626126577458232 ctai_autogen/mocs_compilation.cpp da3870ebc94b983e
17 281 7626126577458232 F:/SourceCode/ctai/build/ctai_autogen/timestamp da3870ebc94b983e
17 281 7626126577458232 F:/SourceCode/ctai/build/ctai_autogen/mocs_compilation.cpp da3870ebc94b983e
282 1037 7626126587503169 qrc_res.cpp 9794859fafc6825 282 1037 7626126587503169 qrc_res.cpp 9794859fafc6825
282 1037 7626126587503169 F:/SourceCode/ctai/build/qrc_res.cpp 9794859fafc6825 4742 18062 7626095344408993 CMakeFiles/ctai.dir/src/sui.cpp.obj 42bed78c7899bffd
1040 3803 7626126587682989 CMakeFiles/ctai.dir/qrc_res.cpp.obj dd75527ee8dace65 18 4707 7626178974330825 F:/SourceCode/ctai/build/ctai_autogen/mocs_compilation.cpp da3870ebc94b983e
1037 34133 7626126587638131 CMakeFiles/ctai.dir/src/ctai_session_info.cpp.obj d12cfe3d50990a54 46038 56681 7626179388667379 F:/SourceCode/ctai/release/ctai.exe bbede5bc6dd5d74a
34133 46017 7626126918603861 F:/SourceCode/ctai/release/ctai.exe bbede5bc6dd5d74a 4745 24869 7626095344451563 CMakeFiles/ctai.dir/src/sui_base_ex.cpp.obj 4278f5aab5827fc6
4722 40298 7626178975502704 CMakeFiles/ctai.dir/src/main.cpp.obj cdab1c27daa47f87
7096 13484 7624392729149768 CMakeFiles/ctai.dir/src/ctai_session_table.cpp.obj 5bacfc2db149ebf7
27 4841 7626186990787268 ctai_autogen/timestamp da3870ebc94b983e
27 4841 7626186990787268 ctai_autogen/mocs_compilation.cpp da3870ebc94b983e
27 4841 7626186990787268 F:/SourceCode/ctai/build/ctai_autogen/timestamp da3870ebc94b983e
27 4841 7626186990787268 F:/SourceCode/ctai/build/ctai_autogen/mocs_compilation.cpp da3870ebc94b983e
4845 38476 7626186991899501 CMakeFiles/ctai.dir/src/ctai_history_textedit.cpp.obj 9afc647ddec3b160
4848 38502 7626186991911900 CMakeFiles/ctai.dir/src/ctai_history_widget.cpp.obj ff767b1a439cfa8f
4854 42324 7626186991972333 CMakeFiles/ctai.dir/src/ctai_tabwidget.cpp.obj 30e97d05c008cea2
4852 43426 7626186991952352 CMakeFiles/ctai.dir/src/ctai_session_widget.cpp.obj 44a14cc778bf0b
4856 43949 7626186991997495 CMakeFiles/ctai.dir/src/main.cpp.obj cdab1c27daa47f87
4850 44083 7626186991942360 CMakeFiles/ctai.dir/src/ctai_session_info.cpp.obj d12cfe3d50990a54
4844 47745 7626186991877447 CMakeFiles/ctai.dir/src/ctai.cpp.obj f1f03f3c05222920
4842 49598 7626186991858828 CMakeFiles/ctai.dir/ctai_autogen/mocs_compilation.cpp.obj 17adb079db0c1349
49599 62092 7626187439419987 F:/SourceCode/ctai/release/ctai.exe bbede5bc6dd5d74a
19 294 7626189314556534 ctai_autogen/timestamp da3870ebc94b983e
19 294 7626189314556534 ctai_autogen/mocs_compilation.cpp da3870ebc94b983e
19 294 7626189314556534 F:/SourceCode/ctai/build/ctai_autogen/timestamp da3870ebc94b983e
19 294 7626189314556534 F:/SourceCode/ctai/build/ctai_autogen/mocs_compilation.cpp da3870ebc94b983e
295 25940 7626189317306680 CMakeFiles/ctai.dir/src/ctai_history_textedit.cpp.obj 9afc647ddec3b160
25940 38380 7626189573770446 F:/SourceCode/ctai/release/ctai.exe bbede5bc6dd5d74a
19 249 7626190002126353 ctai_autogen/timestamp da3870ebc94b983e
19 249 7626190002126353 ctai_autogen/mocs_compilation.cpp da3870ebc94b983e
19 249 7626190002126353 F:/SourceCode/ctai/build/ctai_autogen/timestamp da3870ebc94b983e
19 249 7626190002126353 F:/SourceCode/ctai/build/ctai_autogen/mocs_compilation.cpp da3870ebc94b983e
250 23941 7626190004429008 CMakeFiles/ctai.dir/src/ctai_history_widget.cpp.obj ff767b1a439cfa8f
23942 34788 7626190241357552 F:/SourceCode/ctai/release/ctai.exe bbede5bc6dd5d74a
20 248 7626194102965162 ctai_autogen/timestamp da3870ebc94b983e
20 248 7626194102965162 ctai_autogen/mocs_compilation.cpp da3870ebc94b983e
20 248 7626194102965162 F:/SourceCode/ctai/build/ctai_autogen/timestamp da3870ebc94b983e
20 248 7626194102965162 F:/SourceCode/ctai/build/ctai_autogen/mocs_compilation.cpp da3870ebc94b983e
249 25955 7626194105249164 CMakeFiles/ctai.dir/src/ctai_history_textedit.cpp.obj 9afc647ddec3b160
25955 37664 7626194362300410 F:/SourceCode/ctai/release/ctai.exe bbede5bc6dd5d74a

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -17,7 +17,7 @@ ctai_curl::~ctai_curl()
size_t stream_callback(void *buffer, size_t sz, size_t nmemb, void *userdata) size_t stream_callback(void *buffer, size_t sz, size_t nmemb, void *userdata)
{ {
auto ctx = static_cast<call_back_context *>(userdata); auto ctx = static_cast<call_back_context *>(userdata);
std::unique_lock<std::mutex> lock(ctx->instance->m_mutex); std::lock_guard<std::mutex> lock(ctx->instance->m_mutex);
size_t size = sz * nmemb; size_t size = sz * nmemb;
std::string chunk(static_cast<char *>(buffer), size); std::string chunk(static_cast<char *>(buffer), size);
if (ctx->m_data.postback_stream_mode) if (ctx->m_data.postback_stream_mode)
@ -25,7 +25,6 @@ size_t stream_callback(void *buffer, size_t sz, size_t nmemb, void *userdata)
ctx->instance->send_stream(ctx->m_data, chunk); ctx->instance->send_stream(ctx->m_data, chunk);
} }
qDebug() << "steam data chunk:" << chunk; qDebug() << "steam data chunk:" << chunk;
lock.unlock();
return sz * nmemb; return sz * nmemb;
} }
// 非流式输出回调 // 非流式输出回调

View File

@ -61,26 +61,30 @@ void ctai_history_textedit::init_layout(msg_type msg_type_mode)
m_msg_user_del->setObjectName("m_msg_user_del"); m_msg_user_del->setObjectName("m_msg_user_del");
header_info_Layout->addWidget(m_msg_user_del); header_info_Layout->addWidget(m_msg_user_del);
} }
// 4.分割线区域
// 4. 历史信息QTextEdit hLine = new QFrame;
hLine->setFrameShape(QFrame::HLine); // 关键属性
hLine->setLineWidth(1); // 线宽
// 5. 历史信息QTextEdit
historyLayout = new QVBoxLayout(); historyLayout = new QVBoxLayout();
m_msg_history = new QTextEdit(); m_msg_history = new QTextEdit();
m_msg_history->setAcceptRichText(true); m_msg_history->setAcceptRichText(true);
m_msg_history->setLineWrapMode(QTextEdit::WidgetWidth);
m_msg_history->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); m_msg_history->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// 启用ViewportAttribute以优化渲染
m_msg_history->viewport()->setAttribute(Qt::WA_OpaquePaintEvent);
// 添加性能优化设置
m_msg_history->setUndoRedoEnabled(false); // 禁用撤销重做
m_msg_history->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
m_msg_history->setObjectName("m_msg_history"); m_msg_history->setObjectName("m_msg_history");
m_msg_history->setReadOnly(true); m_msg_history->setReadOnly(true);
historyLayout->addWidget(m_msg_history); historyLayout->addWidget(m_msg_history);
historyLayout->addWidget(hLine);
historyLayout->setContentsMargins(0, 0, 0, 0); historyLayout->setContentsMargins(0, 0, 0, 0);
// 5.分割线区域
QFrame *hLine = new QFrame;
hLine->setFrameShape(QFrame::HLine); // 关键属性
hLine->setFrameShadow(QFrame::Sunken); // 凹陷效果
hLine->setLineWidth(2); // 线宽
// 组合布局 // 组合布局
mainLayout->addLayout(headerLayout); mainLayout->addLayout(headerLayout);
mainLayout->addLayout(historyLayout); mainLayout->addLayout(historyLayout);
mainLayout->addWidget(hLine);
mainLayout->addItem(bottom_spacer); mainLayout->addItem(bottom_spacer);
mainLayout->setStretch(0, 1); mainLayout->setStretch(0, 1);
mainLayout->setSpacing(1); mainLayout->setSpacing(1);
@ -107,44 +111,65 @@ void ctai_history_textedit::connect_signals(msg_type msg_type_mode)
} }
void ctai_history_textedit::on_text_height() void ctai_history_textedit::on_text_height()
{ {
// 强制立即更新文档布局 // 防抖动处理如果上次更新在100ms内则延迟处理
m_msg_history->document()->adjustSize(); static QTimer debounceTimer;
debounceTimer.setSingleShot(true);
// 获取文档尺寸前确保布局已更新 if (debounceTimer.isActive())
m_msg_history->document()->setTextWidth(m_msg_history->viewport()->width());
// 获取文档尺寸
QSize docSize = m_msg_history->document()->size().toSize();
qDebug() << "文档宽度:" << m_msg_history->document()->textWidth();
qDebug() << "文档实际高度:" << docSize.height();
if (docSize.height() == 0)
{ {
// 如果高度仍为0使用替代方法计算 return;
int textHeight = m_msg_history->document()->documentLayout()->documentSize().height();
docSize.setHeight(textHeight);
} }
// 计算实际需要的高度 (包含边距和视口边框) // 使用viewport宽度作为缓存
int newHeight = docSize.height() + static int lastWidth = 0;
m_msg_history->document()->documentMargin() * 2 + int currentWidth = m_msg_history->viewport()->width();
m_msg_history->frameWidth() * 2;
// 保存折叠前的高度 // 只在宽度变化时才重新计算
m_original_height = newHeight; if (lastWidth != currentWidth)
// 设置新的固定高度 {
if (m_msg_history->height() != newHeight) { m_msg_history->document()->setTextWidth(currentWidth);
m_msg_history->setFixedHeight(newHeight); lastWidth = currentWidth;
emit height_changed(); // 发送高度变化信号 }
// 强制更新几何布局 // 直接使用documentLayout获取高度避免多次计算
updateGeometry(); int textHeight = m_msg_history->document()->documentLayout()->documentSize().height();
// 通知父容器重新计算所有项的大小 if (textHeight > 0)
if (QWidget *parent = parentWidget()) { {
QEvent e(QEvent::LayoutRequest); // 计算实际需要的高度 (包含边距和视口边框)
QApplication::sendEvent(parent, &e); int newHeight = textHeight +
m_msg_history->document()->documentMargin() * 2 +
m_msg_history->frameWidth() * 2;
// 添加高度阈值判断,避免微小变化触发更新
static const int HEIGHT_THRESHOLD = 5; // 5像素的阈值
if (abs(m_msg_history->height() - newHeight) > HEIGHT_THRESHOLD)
{
m_original_height = newHeight;
// 批量更新布局
bool wasBlocked = m_msg_history->signalsBlocked();
m_msg_history->blockSignals(true);
m_msg_history->setFixedHeight(newHeight);
updateGeometry();
m_msg_history->blockSignals(wasBlocked);
emit height_changed();
// 延迟发送布局更新请求
if (QWidget *parent = parentWidget())
{
QTimer::singleShot(100, [parent]()
{
QEvent e(QEvent::LayoutRequest);
QApplication::sendEvent(parent, &e); });
}
} }
} }
// 设置下一次检查的延迟
debounceTimer.start(100);
} }
// tokens按钮实现功能的槽函数 // tokens按钮实现功能的槽函数
void ctai_history_textedit::on_tokens_clicked() void ctai_history_textedit::on_tokens_clicked()
@ -189,22 +214,22 @@ void ctai_history_textedit::on_save_clicked()
} }
if (!m_msg_save_text) if (!m_msg_save_text)
{ {
m_msg_save_text = new QAction(tr("存为文本")); m_msg_save_text = new QAction(tr("存为文本"));
connect(m_msg_save_text, SIGNAL(triggered(bool)), this, SLOT(on_save_text())); connect(m_msg_save_text, SIGNAL(triggered(bool)), this, SLOT(on_save_text()));
} }
if (!m_msg_save_html) if (!m_msg_save_html)
{ {
m_msg_save_html = new QAction(tr("存为HTML")); m_msg_save_html = new QAction(tr("存为HTML"));
connect(m_msg_save_html, SIGNAL(triggered(bool)), this, SLOT(on_save_html())); connect(m_msg_save_html, SIGNAL(triggered(bool)), this, SLOT(on_save_html()));
} }
if (!m_msg_save_markdown) if (!m_msg_save_markdown)
{ {
m_msg_save_markdown = new QAction(tr("存为Markdown")); m_msg_save_markdown = new QAction(tr("存为Markdown"));
connect(m_msg_save_markdown, SIGNAL(triggered(bool)), this, SLOT(on_save_markdown())); connect(m_msg_save_markdown, SIGNAL(triggered(bool)), this, SLOT(on_save_markdown()));
} }
if (!m_msg_save_pdf) if (!m_msg_save_pdf)
{ {
m_msg_save_pdf = new QAction(tr("存为PDF")); m_msg_save_pdf = new QAction(tr("存为PDF"));
connect(m_msg_save_pdf, SIGNAL(triggered(bool)), this, SLOT(on_save_pdf())); connect(m_msg_save_pdf, SIGNAL(triggered(bool)), this, SLOT(on_save_pdf()));
} }
m_msg_save_menu->addAction(m_msg_save_text); m_msg_save_menu->addAction(m_msg_save_text);
@ -225,6 +250,7 @@ void ctai_history_textedit::on_fold_clicked()
} }
void ctai_history_textedit::add_message(const model_data &message) void ctai_history_textedit::add_message(const model_data &message)
{ {
std::lock_guard<std::mutex> lock(m_mutex);
QString disp_data; QString disp_data;
QString disp_header; QString disp_header;
if (message.msg_type_mode == SYSTEM) if (message.msg_type_mode == SYSTEM)
@ -263,9 +289,10 @@ void ctai_history_textedit::on_copy_clicked()
void ctai_history_textedit::on_save_text() void ctai_history_textedit::on_save_text()
{ {
QString fileName = QFileDialog::getSaveFileName(this, QString fileName = QFileDialog::getSaveFileName(this,
tr("保存消息"), "", tr("保存消息"), m_msg_sned_id + ".txt",
tr("文本文件 (*.txt);;所有文件 (*)")); tr("文本文件 (*.txt)"));
if (fileName.isEmpty()) if (fileName.isEmpty())
return; return;
@ -279,9 +306,7 @@ void ctai_history_textedit::on_save_text()
} }
QTextStream out(&file); QTextStream out(&file);
out << m_msg_header->text() << "\n\n";
out << m_msg_history->toPlainText() << "\n\n"; out << m_msg_history->toPlainText() << "\n\n";
out << m_msg_tokens->text();
} }
void ctai_history_textedit::on_save_html() void ctai_history_textedit::on_save_html()
{ {

View File

@ -17,6 +17,8 @@
#include <QMenu> #include <QMenu>
#include <QFileDialog> #include <QFileDialog>
#include <QMessageBox> #include <QMessageBox>
#include <QTimer>
#include <mutex>
#include <QAbstractTextDocumentLayout> #include <QAbstractTextDocumentLayout>
#include "ctai_base.h" #include "ctai_base.h"
#include "ctai_parsestring.h" #include "ctai_parsestring.h"
@ -33,6 +35,8 @@ typedef struct tokens_args{
QString cache_miss_tokens={}; QString cache_miss_tokens={};
}tokens_data; }tokens_data;
std::mutex m_mutex;
class ctai_history_textedit : public QWidget class ctai_history_textedit : public QWidget
{ {
Q_OBJECT Q_OBJECT
@ -59,6 +63,7 @@ private:
void init_layout(msg_type msg_type_mode); void init_layout(msg_type msg_type_mode);
void connect_signals(msg_type msg_type_mode); // 连接信号和槽 void connect_signals(msg_type msg_type_mode); // 连接信号和槽
private: private:
QFrame *hLine;
QSpacerItem *sparcer_item = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Fixed); QSpacerItem *sparcer_item = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Fixed);
QVBoxLayout *mainLayout={}; QVBoxLayout *mainLayout={};
QVBoxLayout *headerLayout={}; QVBoxLayout *headerLayout={};

View File

@ -16,7 +16,7 @@ void ctai_history_widget::setup_table()
verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
// 设置自动滚动属性 // 设置自动滚动属性
setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
//滚动步长 // 滚动步长
verticalScrollBar()->setSingleStep(10); verticalScrollBar()->setSingleStep(10);
} }
@ -90,28 +90,16 @@ void ctai_history_widget::add_message(const model_data &message)
} }
void ctai_history_widget::on_widget_height_changed() void ctai_history_widget::on_widget_height_changed()
{ {
// 暂时阻止滚动条更新以避免闪烁 int row = currentRow();
setUpdatesEnabled(false); if (row >= 0 && row < rowCount()) {
int currentHeight = rowHeight(row);
// 保存当前滚动位置 setRowHeight(row, currentHeight + 32);
QScrollBar* vscroll = verticalScrollBar();
bool was_at_bottom = vscroll->value() >= vscroll->maximum() - 10;
// 重新计算所有行高
for (int row = 0; row < rowCount(); ++row) {
resizeRowToContents(row); resizeRowToContents(row);
} }
scrollToBottom();
// 恢复滚动条位置
if (was_at_bottom) {
scrollToBottom();
}
// 重新启用更新
setUpdatesEnabled(true);
} }
void ctai_history_widget::on_msg_remove(QString send_id) void ctai_history_widget::on_msg_remove(QString send_id)
{ {
int row = this->rowCount(); int row = this->rowCount();
if (row >= 0) if (row >= 0)
{ {

View File

@ -48,7 +48,7 @@ void ctai_session_info::init_sub_layout()
m_sub_systeam_widget->setLayout(m_session_systeam_info_layout); m_sub_systeam_widget->setLayout(m_session_systeam_info_layout);
m_session_user_group_layout = new QVBoxLayout(); m_session_user_group_layout = new QVBoxLayout();
m_session_user_edit_info = new QTextEdit(tr("1+1为什么等于2?")); m_session_user_edit_info = new QTextEdit(tr("写一篇关于天然气的论文"));
m_session_user_edit_layout = new QVBoxLayout(); m_session_user_edit_layout = new QVBoxLayout();
m_session_user_edit_layout->addWidget(m_session_user_edit_info); m_session_user_edit_layout->addWidget(m_session_user_edit_info);