调整命令

This commit is contained in:
JackLee 2025-03-29 17:57:47 +08:00
parent 8ff67ba1cd
commit 3799234c56
4 changed files with 175 additions and 133 deletions

View File

@ -52,6 +52,8 @@ CefWidget::CefWidget(QWidget *parent)
m_Layout->setStretch(1, 8);
setBaseSize(QSize(width(),height()));
setLayout(m_Layout);
setWindowFlags(Qt::Window); // 使用标准窗口样式
setAttribute(Qt::WA_TranslucentBackground, false);
initBrowser();
}
@ -66,7 +68,10 @@ void CefWidget::initBrowser()
m_CefWidget->deleteLater();
m_CefWidget = nullptr;
}
setting.setWindowlessFrameRate(1000);
setting.setHardwareAcceleration(true);
QColor background(0, 255, 0, 255);
setting.setBackgroundColor(background);
m_CefWidget = new QCefView("about:blank", &setting, this);
connect(m_CefWidget, &QCefView::invokeMethod, this, &CefWidget::onInvokeMethod);
connect(m_CefWidget, &QCefView::cefUrlRequest, this, &CefWidget::onQCefUrlRequest);

View File

@ -10,11 +10,12 @@ ctaiHistoryTextEdit::~ctaiHistoryTextEdit()
}
void ctaiHistoryTextEdit::initLayout(msg_type msg_type_mode)
{
m_msg_type = msg_type_mode;
// 主垂直布局
main_layout = new QVBoxLayout();
initMsgLine();
initMsgHeaderLayout(msg_type_mode);
initMsgHistoryLayout(msg_type_mode);
initMsgHeaderLayout();
initMsgHistoryLayout();
// 主布局
main_layout->addLayout(header_layout);
main_layout->addLayout(history_layout);
@ -24,7 +25,7 @@ void ctaiHistoryTextEdit::initLayout(msg_type msg_type_mode)
main_layout->setContentsMargins(0, 0, 0, 0);
setLayout(main_layout);
set_default_opts();
connect_signals(msg_type_mode);
connect_signals();
}
void ctaiHistoryTextEdit::initMsgLine()
{
@ -34,23 +35,32 @@ void ctaiHistoryTextEdit::initMsgLine()
msg_line->setFrameShadow(QFrame::Sunken); // 凹陷效果
msg_line->setLineWidth(2); // 线宽
}
void ctaiHistoryTextEdit::initMsgHistoryLayout(msg_type msg_type_mode)
void ctaiHistoryTextEdit::initMsgHistoryLayout()
{
history_layout = new QVBoxLayout();
// 历史信息QTextEdit
m_msg_history = new QTextEdit();
m_math_convert = new ctaiMathConvert();
m_msg_history->setUndoRedoEnabled(false); // 关闭撤销历史以节省内存
m_msg_history->setAcceptRichText(true);
m_msg_history->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_msg_history->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_msg_history->setObjectName("m_msg_history");
m_msg_history->setReadOnly(true);
history_layout->addWidget(m_msg_history);
if (m_msg_type == USER)
{
m_msg_history = new QTextEdit();
m_math_convert = new ctaiMathConvert();
m_msg_history->setUndoRedoEnabled(false); // 关闭撤销历史以节省内存
m_msg_history->setAcceptRichText(true);
m_msg_history->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_msg_history->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_msg_history->setObjectName("m_msg_history");
m_msg_history->setReadOnly(true);
history_layout->addWidget(m_msg_history);
}
else
{
m_edit_cef = new CefWidget();
m_edit_cef->setMinimumHeight(600);
history_layout->addWidget(m_edit_cef);
}
history_layout->addWidget(msg_line);
history_layout->setContentsMargins(0, 0, 0, 0);
}
void ctaiHistoryTextEdit::initMsgHeaderLayout(msg_type msg_type_mode)
void ctaiHistoryTextEdit::initMsgHeaderLayout()
{
// 消息头左区域布局,ico,id,fp,time
header_info_layout = new QHBoxLayout();
@ -71,7 +81,7 @@ void ctaiHistoryTextEdit::initMsgHeaderLayout(msg_type msg_type_mode)
m_restart_to_send->setObjectName("m_restart_to_send");
m_msg_fold->setIcon(QIcon(":res/img/btn/btn_info_up.png"));
m_msg_fold->setIconSize(QSize(25, 25));
if (msg_type_mode == SYSTEM)
if (m_msg_type == SYSTEM)
{
// 1.SYSTEM消息头水平左信息区
m_msg_system_header_ico = new QPushButton();
@ -110,11 +120,14 @@ void ctaiHistoryTextEdit::initMsgHeaderLayout(msg_type msg_type_mode)
}
void ctaiHistoryTextEdit::set_default_opts()
{
m_msg_history->setFont(QFont(m_msg_tools->getFont(), m_msg_tools->getFontSize().toInt()));
if (m_msg_type == USER)
{
m_msg_history->setFont(QFont(m_msg_tools->getFont(), m_msg_tools->getFontSize().toInt()));
}
}
void ctaiHistoryTextEdit::connect_signals(msg_type msg_type_mode)
void ctaiHistoryTextEdit::connect_signals()
{
if (msg_type_mode == SYSTEM)
if (m_msg_type == SYSTEM)
{
// 复制功能
connect(m_msg_tools, SIGNAL(signalsOnCopy()), this, SLOT(slotsOnCopy()));
@ -131,12 +144,15 @@ void ctaiHistoryTextEdit::connect_signals(msg_type msg_type_mode)
// 其他功能菜单
connect(m_msg_tools, SIGNAL(signalsOnOptsMenu()), this, SLOT(slotsOnOptsMenu()));
}
else
{
connect(m_msg_history, SIGNAL(textChanged()), this, SLOT(slotsOnSyncHeight()));
}
// 删除信息
connect(m_msg_delete, SIGNAL(clicked()), this, SLOT(slotsOnDelete()));
// 折叠信息功能
connect(m_msg_fold, SIGNAL(clicked()), this, SLOT(slotsOnFold()));
// 同步行高
connect(m_msg_history, SIGNAL(textChanged()), this, SLOT(slotsOnSyncHeight()));
// 插入msg到send
connect(m_history_to_send, SIGNAL(clicked()), this, SLOT(slotsHisResToSend()));
// 重试send
@ -164,7 +180,10 @@ void ctaiHistoryTextEdit::slotsOnOptsMenu()
}
void ctaiHistoryTextEdit::slotsOnDisplayFontSize()
{
m_msg_history->setFont(QFont(m_msg_tools->getFont(), m_msg_tools->getFontSize().toInt()));
if (m_msg_type == USER)
{
m_msg_history->setFont(QFont(m_msg_tools->getFont(), m_msg_tools->getFontSize().toInt()));
}
}
void ctaiHistoryTextEdit::slotsOnDelete()
{
@ -174,9 +193,12 @@ void ctaiHistoryTextEdit::slotsOnDelete()
void ctaiHistoryTextEdit::slotsOnCopy()
{
// 获取文本并复制到剪贴板
QString text = m_msg_history->toPlainText();
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(text);
if (m_msg_type == USER)
{
QString text = m_msg_history->toPlainText();
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(text);
}
}
void ctaiHistoryTextEdit::slotsOnSave(QString save_path, int index)
{
@ -216,7 +238,9 @@ void ctaiHistoryTextEdit::slotsOnSave(QString save_path, int index)
void ctaiHistoryTextEdit::slotsOnFold()
{
m_is_folded = !m_is_folded;
m_msg_history->setFixedHeight(m_is_folded ? 0 : m_original_height);
if(m_msg_type==USER){
m_msg_history->setFixedHeight(m_is_folded ? 0 : m_original_height);
}
m_msg_fold->setIcon(QIcon(m_is_folded ? ":res/img/btn/btn_info_down.png" : ":res/img/btn/btn_info_up.png"));
updateGeometry();
emit signalsRowHeightChanged(m_is_folded);
@ -281,37 +305,41 @@ void ctaiHistoryTextEdit::slotsOnSyncHeight()
{
return;
}
// 直接使用documentLayout获取高度避免多次计算
int textHeight = m_msg_history->document()->documentLayout()->documentSize().height();
if (textHeight > 0)
if (m_msg_type == USER)
{
// 计算实际需要的高度 (包含边距和视口边框)
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)
// 直接使用documentLayout获取高度避免多次计算
int textHeight = m_msg_history->document()->documentLayout()->documentSize().height();
if (textHeight > 0)
{
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 signalsRowHeightChanged(false);
// 计算实际需要的高度 (包含边距和视口边框)
int newHeight = textHeight +
m_msg_history->document()->documentMargin() * 2 +
m_msg_history->frameWidth() * 2;
// 延迟发送布局更新请求
if (QWidget *parent = parentWidget())
// 添加高度阈值判断,避免微小变化触发更新
static const int HEIGHT_THRESHOLD = 5; // 5像素的阈值
if (abs(m_msg_history->height() - newHeight) > HEIGHT_THRESHOLD)
{
QTimer::singleShot(100, [parent]()
{
QEvent e(QEvent::LayoutRequest);
QApplication::sendEvent(parent, &e); });
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 signalsRowHeightChanged(false);
// 延迟发送布局更新请求
if (QWidget *parent = parentWidget())
{
QTimer::singleShot(100, [parent]()
{
QEvent e(QEvent::LayoutRequest);
QApplication::sendEvent(parent, &e); });
}
}
}
}
// 设置下一次检查的延迟
debounceTimer.start(100);
}
@ -330,6 +358,7 @@ void ctaiHistoryTextEdit::addSystemMessage(const model_data &message)
{
// 流式模式下追加内容
m_current_content += message.postback_model_data;
m_edit_cef->onCallJsCode(QSL(message.postback_model_data));
}
else
{
@ -337,7 +366,7 @@ void ctaiHistoryTextEdit::addSystemMessage(const model_data &message)
m_current_content = QSL(message.postback_model_data);
}
m_msg_history->setMarkdown(m_current_content);
// m_msg_history->setMarkdown(m_current_content);
}
// 增加tokens信息
void ctaiHistoryTextEdit::updateTokensMessage(const model_data &message)

View File

@ -37,6 +37,7 @@
#include "ctai_base.h"
#include "ctaiMathConvert.h"
#include "ctaiHistoryTools.h"
#include "QCefWidget/CefWidget.h"
std::mutex m_mutex;
class ctaiHistoryTextEdit : public QWidget
{
@ -45,8 +46,8 @@ public:
ctaiHistoryTextEdit(QWidget *parent = nullptr);
~ctaiHistoryTextEdit();
void initLayout(msg_type msg_type_mode);
void initMsgHeaderLayout(msg_type msg_type_mode);
void initMsgHistoryLayout(msg_type msg_type_mode);
void initMsgHeaderLayout();
void initMsgHistoryLayout();
void initMsgLine();
void addUserMessage(const model_data &message);
void addSystemMessage(const model_data &message);
@ -69,11 +70,12 @@ signals:
void signalsRowHeightChanged(bool);
void signalsEditHisResToSend(QString,HISTORY_SEND_MODE);
private:
void connect_signals(msg_type msg_type_mode); // 连接信号和槽
void connect_signals(); // 连接信号和槽
void set_default_opts();
private:
ctaiMathConvert *m_math_convert;
QFrame *msg_line;
CefWidget *m_edit_cef;
QFrame *msg_line;
QSpacerItem *sparcer_item = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Fixed);
QVBoxLayout *main_layout = {};
QVBoxLayout *header_layout = {};
@ -111,6 +113,8 @@ private:
QString m_msg_sned_id = {};
// 本次信息
QString m_current_content;
//任务类型
msg_type m_msg_type;
//粗体字
bool m_bold=false;
std::vector<QString> save_extend={".txt",".html",".md",".pdf"};

View File

@ -11,102 +11,107 @@
#define DEBUG_PRINT true
void debug_print_argv(int argc, char *argv[])
{
if(!argc){
if (!argc)
{
return;
}
std::lock_guard<std::mutex> lock(m_mutex);
DWORD process_id = GetCurrentProcessId();
std::cout << "Process ID:"<<process_id<<" Argvs"<<std::endl;
std::cout << "CurrentProcessId Argvs" << std::endl;
for (int i = 0; i < argc; ++i)
{
std::cout << "Process ID:"<<process_id<<" Argv:" << i << ": " << argv[i]<<std::endl;
std::cout << "Process ID:" << process_id << " Argv:" << i << ": " << argv[i] << std::endl;
}
}
QString curExeDir(){
QString curExeDir()
{
return QDir::currentPath();
}
void exsMkDir(QString Dir){
if(!QDir(Dir).exists()){
void exsMkDir(QString Dir)
{
if (!QDir(Dir).exists())
{
QDir().mkdir(Dir);
}
}
bool exeCinfog(int argc,char *argv[]){
if(argc<=0){
return true;
}
std::string ex_1="renderer";
std::string ex_2="utility";
for (int i = 0; i < argc; ++i){
bool exeCinfog(int argc, char *argv[])
{
std::string ex_1 = "renderer";
std::string ex_2 = "utility";
for (int i = 0; i < argc; i++)
{
std::string arg = argv[i];
if (arg.find(ex_1) == std::string::npos||arg.find(ex_2)== std::string::npos){
return true;
if (arg.find(ex_1) == std::string::npos || arg.find(ex_2) == std::string::npos)
{
return true;
}
}
return false;
}
void initConfig(int argc,char *argv[],QCefConfig &config,QString currentDir)
void initConfig(int argc, char *argv[], QCefConfig &config, QString currentDir)
{
//检测自定义缓存路径
exsMkDir(currentDir+"/user");
exsMkDir(currentDir+"/user/userCache");
//子进程路径和名字,可以利用本进程复用,
//Mingw编译下多进程情况需要设置否则程序会退出因为无法拉起子进程
if(exeCinfog(argc,argv)){
config.setBrowserSubProcessPath(currentDir+"/ctai.exe");
// 检测自定义缓存路径
exsMkDir(currentDir + "/user");
exsMkDir(currentDir + "/user/userCache");
// 子进程路径和名字,可以利用本进程复用,
// Mingw编译下多进程情况需要设置否则程序会退出因为无法拉起子进程
if (exeCinfog(argc, argv))
{
config.setBrowserSubProcessPath(currentDir + "/ctai.exe");
}
config.setRootCachePath(currentDir+"/user");
config.setCachePath(currentDir+"/user/userCache");
config.setResourceDirectoryPath(currentDir+"/cef_binary");
config.setLocalesDirectoryPath(currentDir+"/cef_binary/locales");
//浏览器标识
config.setRootCachePath(currentDir + "/user");
config.setCachePath(currentDir + "/user/userCache");
config.setResourceDirectoryPath(currentDir + "/cef_binary");
config.setLocalesDirectoryPath(currentDir + "/cef_binary/locales");
// 浏览器标识
config.setUserAgent("Mozilla/5.0 (Windows NT 10.0; CEF/3.2272.2035) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 SoftwareInformer/1.6.1400");
//日志输出级别
// 日志输出级别
config.setLogLevel(QCefConfig::LOGSEVERITY_VERBOSE);
//桥名字
// 桥名字
config.setBridgeObjectName("CtaiClient");
//内置的协议方案名称
// 内置的协议方案名称
config.setBuiltinSchemeName("Ctai");
//无窗口渲染模式
config.setWindowlessRenderingEnabled(true);
//远程Debug端口
//config.setRemoteDebuggingPort(9000);
//请求头的语言
// 无窗口渲染模式
// config.setWindowlessRenderingEnabled(true);
// 远程Debug端口
// config.setRemoteDebuggingPort(9000);
// 请求头的语言
config.setAcceptLanguageList("zh-CN");
//允许忽略 localhost 上的 TLS/SSL 错误
// 允许忽略 localhost 上的 TLS/SSL 错误
config.addCommandLineSwitch("allow-insecure-localhost");
config.addCommandLineSwitch("ignore-certificate-errors-spki-list");
config.addCommandLineSwitch("ignore-ssl-errors");
//单进程模式
// config.addCommandLineSwitch("single-process");
//启用GPU加速
// 单进程模式
// config.addCommandLineSwitch("single-process");
// 启用GPU加速
config.addCommandLineSwitch("enable-gpu");
//GPU加速合成
// GPU加速合成
config.addCommandLineSwitch("enable-gpu-compositing");
//在进程中使用GPU渲染-开启后只有一个进程
// 在进程中使用GPU渲染-开启后只有一个进程
config.addCommandLineSwitch("in-process-gpu");
//无头模式
config.addCommandLineSwitch("headless");
//密钥链
// 无头模式
// config.addCommandLineSwitch("headless");
// 密钥链
config.addCommandLineSwitch("use-mock-keychain");
//chrome运行时环境
// chrome运行时环境
config.addCommandLineSwitch("enable-chrome-runtime");
//Alloy 风格
// Alloy 风格
config.addCommandLineSwitch("use-alloy-style");
//离屏渲染
config.addCommandLineSwitch("off-screen-rendering-enabled");
//网络服务In进程
// 离屏渲染
// config.addCommandLineSwitch("off-screen-rendering-enabled");
// 网络服务In进程
config.addCommandLineSwitchWithValue("enable-features", "NetworkServiceInProcess");
//语言
// 语言
config.addCommandLineSwitchWithValue("lang", "zh-CN");
//跨域进行远程
//config.addCommandLineSwitchWithValue("remote-allow-origins", "*");
// 禁用沙盒
// 跨域进行远程
// config.addCommandLineSwitchWithValue("remote-allow-origins", "*");
// 禁用沙盒
config.addCommandLineSwitchWithValue("no-sandbox", "ture");
//渲染进程限制
// 渲染进程限制
config.addCommandLineSwitchWithValue("renderer-process-limit", "1");
//外部消息循环
// 外部消息循环
config.addCommandLineSwitchWithValue("external-message-pump", "false");
//多线程消息循环
// 多线程消息循环
config.addCommandLineSwitchWithValue("multi-threaded-message-loop", "true");
}
int main(int argc, char *argv[])
@ -117,32 +122,31 @@ int main(int argc, char *argv[])
}
QApplication a(argc, argv);
QCefConfig config;
//初始化上下文的配置
initConfig(argc,argv,config,curExeDir());
//初始化浏览器上下文
// 初始化上下文的配置
initConfig(argc, argv, config, curExeDir());
// 初始化浏览器上下文
QCefContext cefContext(&a, argc, argv, &config);
//初始化浏览器
CefWidget cw;
cw.show();
// qputenv("QT_QPA_PLATFORM", "windows:fontengine=freetype");
// // 加载语言包
// QTranslator qtBaseTranslator;
// if (!qtBaseTranslator.load(QStringLiteral(":/res/translator/qtbase_zh_CN.qm")))
// {
// // 处理加载翻译文件失败的情况
// qDebug() << "Failed to load translation file.";
// return -1;
// }
// a.installTranslator(&qtBaseTranslator);
// // 读取窗体的配置并初始化
// sui_init_config();
// ctai x;
// x.init_layout();
// // 仅限于windows平台
// #if defined(__WIN32__)
// x.title()->set_type(QD_TYPE::QD_EXIT);
// #endif
// x.show();
qputenv("QT_QPA_PLATFORM", "windows:fontengine=freetype");
// 加载语言包
QTranslator qtBaseTranslator;
if (!qtBaseTranslator.load(QStringLiteral(":/res/translator/qtbase_zh_CN.qm")))
{
// 处理加载翻译文件失败的情况
qDebug() << "Failed to load translation file.";
return -1;
}
a.installTranslator(&qtBaseTranslator);
// 读取窗体的配置并初始化
sui_init_config();
ctai x;
x.init_layout();
// 仅限于windows平台
#if defined(__WIN32__)
x.title()->set_type(QD_TYPE::QD_EXIT);
#endif
x.show();
a.exec();
qDebug() << "EXIT";
return 0;