From 6940157f6abad2be4ccbe0409384c2c7d20e5b6b Mon Sep 17 00:00:00 2001 From: JackLee <809262979@qq.com> Date: Mon, 24 Mar 2025 00:18:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AF=B9=E6=9C=AC=E5=9C=B0ht?= =?UTF-8?q?ml=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/QCefWidget/CefViewWidget.cpp | 44 ++++-------- src/QCefWidget/CefViewWidget.h | 17 +---- src/QCefWidget/CefWidget.cpp | 111 +++++++++++++++++++------------ src/QCefWidget/CefWidget.h | 8 ++- src/ctaiHistoryTextEdit.cpp | 51 ++++++++------ src/ctaiHistoryTextEdit.h | 2 +- src/ctaiMathConvert.cpp | 22 ++++-- src/ctaiMathConvert.h | 9 +-- src/main.cpp | 38 +++++------ 9 files changed, 159 insertions(+), 143 deletions(-) diff --git a/src/QCefWidget/CefViewWidget.cpp b/src/QCefWidget/CefViewWidget.cpp index 24d6e30..9abf75a 100644 --- a/src/QCefWidget/CefViewWidget.cpp +++ b/src/QCefWidget/CefViewWidget.cpp @@ -3,10 +3,7 @@ CefViewWidget::CefViewWidget(const QString url, const QCefSetting* setting, QWidget* parent /* = 0*/) : QCefView(url, setting, parent) { - // setStyleSheet("background: blue;"); - - connect(this, &CefViewWidget::draggableRegionChanged, this, &CefViewWidget::onDraggableRegionChanged); - connect(this, &CefViewWidget::nativeBrowserCreated, this, &CefViewWidget::onNativeBrowserWindowCreated); + connect(this, &CefViewWidget::nativeBrowserCreated, this, &CefViewWidget::onNativeBrowserWindowCreated); } CefViewWidget::~CefViewWidget() {} @@ -16,8 +13,6 @@ CefViewWidget::onScreenChanged(QScreen* screen) { if (!m_pCefWindow) return; - - updateMask(); } void @@ -28,15 +23,6 @@ CefViewWidget::onNativeBrowserWindowCreated(QWindow* window) return; connect(this->window()->windowHandle(), SIGNAL(screenChanged(QScreen*)), this, SLOT(onScreenChanged(QScreen*))); - - updateMask(); -} - -void -CefViewWidget::onDraggableRegionChanged(const QRegion& draggableRegion, const QRegion& nonDraggableRegion) -{ - m_draggableRegion = draggableRegion; - m_nonDraggableRegion = nonDraggableRegion; } bool @@ -73,10 +59,6 @@ CefViewWidget::onUpdateDownloadItem(const QSharedPointer& item void CefViewWidget::resizeEvent(QResizeEvent* event) { - // update mask first, because the new mask will be - // used in the QCefView::resizeEvent - updateMask(); - QCefView::resizeEvent(event); } @@ -84,23 +66,23 @@ void CefViewWidget::mousePressEvent(QMouseEvent* event) { QCefView::mousePressEvent(event); - if (event->buttons().testFlag(Qt::LeftButton) && m_draggableRegion.contains(event->pos())) { - HWND hWnd = ::GetAncestor((HWND)(window()->windowHandle()->winId()), GA_ROOT); - POINT pt; - ::GetCursorPos(&pt); - ::ReleaseCapture(); - ::SendMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, POINTTOPOINTS(pt)); - } + // if (event->buttons().testFlag(Qt::LeftButton)) { + // HWND hWnd = ::GetAncestor((HWND)(window()->windowHandle()->winId()), GA_ROOT); + // POINT pt; + // ::GetCursorPos(&pt); + // ::ReleaseCapture(); + // ::SendMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, POINTTOPOINTS(pt)); + // } } void CefViewWidget::updateMask() { // create a rect with rounded corner (50px radius) as mask - QPainterPath path; - path.addRoundedRect(rect(), 0, 0); - QRegion mask = QRegion(path.toFillPolygon().toPolygon()); + // QPainterPath path; + // path.addRoundedRect(rect(), 0, 0); + // QRegion mask = QRegion(path.toFillPolygon().toPolygon()); - // apply the mask - setMask(mask); + // // apply the mask + // setMask(mask); } diff --git a/src/QCefWidget/CefViewWidget.h b/src/QCefWidget/CefViewWidget.h index a530b08..ffea051 100644 --- a/src/QCefWidget/CefViewWidget.h +++ b/src/QCefWidget/CefViewWidget.h @@ -24,11 +24,7 @@ public: protected slots: void onScreenChanged(QScreen* screen); - void onNativeBrowserWindowCreated(QWindow* window); - - void onDraggableRegionChanged(const QRegion& draggableRegion, const QRegion& nonDraggableRegion); - protected: bool onNewPopup(const QCefFrameId& sourceFrameId, const QString& targetUrl, @@ -39,25 +35,14 @@ protected: bool& disableJavascriptAccess) override; void onNewDownloadItem(const QSharedPointer& item, const QString& suggestedName) override; - void onUpdateDownloadItem(const QSharedPointer& item) override; - protected: void resizeEvent(QResizeEvent* event) override; - void mousePressEvent(QMouseEvent* event) override; - private: void updateMask(); - private: - QWindow* m_pCefWindow = nullptr; - - int m_iCornerRadius = 50; - - QRegion m_draggableRegion; - - QRegion m_nonDraggableRegion; + QWindow* m_pCefWindow = {}; }; #endif // CUSTOMCEFVIEW_H diff --git a/src/QCefWidget/CefWidget.cpp b/src/QCefWidget/CefWidget.cpp index 6974d3e..62f59bb 100644 --- a/src/QCefWidget/CefWidget.cpp +++ b/src/QCefWidget/CefWidget.cpp @@ -17,39 +17,47 @@ CefWidget::CefWidget(QWidget *parent) m_Layout = new QVBoxLayout; m_OptionsLayout = new QHBoxLayout; m_BrowserLayout = new QHBoxLayout; - m_NewBrowser = new QPushButton(tr("New Browser")); - m_ExitAllBrowser = new QPushButton(tr("Exit ALL Browser")); - m_DevTools = new QPushButton(tr("DevTools")); - m_CallJSCode = new QPushButton(tr("Call JS Code")); - m_SetFocus = new QPushButton(tr("Set Focus")); - m_BtnToUrl = new QPushButton(tr("To Url")); - m_TextToUrl = new QLineEdit(); - m_TextToUrl->setPlaceholderText(tr("输入前往url地址")); + if (DevMode) + { + m_NewBrowser = new QPushButton(tr("New Browser")); + m_ExitAllBrowser = new QPushButton(tr("Exit ALL Browser")); + m_DevTools = new QPushButton(tr("DevTools")); + m_CallJSCode = new QPushButton(tr("Call JS Code")); + m_SetFocus = new QPushButton(tr("Set Focus")); + m_BtnToUrl = new QPushButton(tr("To Url")); + m_BtnToString = new QPushButton(tr("To String")); + m_TextToUrl = new QLineEdit(); + m_TextToUrl->setPlaceholderText(tr("输入前往url地址")); - m_OptionsLayout->addWidget(m_NewBrowser); - m_OptionsLayout->addWidget(m_TextToUrl); - m_OptionsLayout->addWidget(m_BtnToUrl); - m_OptionsLayout->addWidget(m_SetFocus); - m_OptionsLayout->addWidget(m_CallJSCode); - m_OptionsLayout->addWidget(m_DevTools); - m_OptionsLayout->addWidget(m_ExitAllBrowser); - m_OptionsLayout->setStretch(1,7); - m_Layout->addLayout(m_OptionsLayout); + m_OptionsLayout->addWidget(m_NewBrowser); + m_OptionsLayout->addWidget(m_TextToUrl); + m_OptionsLayout->addWidget(m_BtnToUrl); + m_OptionsLayout->addWidget(m_BtnToString); + m_OptionsLayout->addWidget(m_SetFocus); + m_OptionsLayout->addWidget(m_CallJSCode); + m_OptionsLayout->addWidget(m_DevTools); + m_OptionsLayout->addWidget(m_ExitAllBrowser); + m_OptionsLayout->setStretch(1, 7); + m_Layout->addLayout(m_OptionsLayout); + connect(m_BtnToUrl, SIGNAL(clicked()), this, SLOT(onBtnToUrl())); + connect(m_BtnToString, SIGNAL(clicked()), this, SLOT(onBtnToString())); + connect(m_DevTools, SIGNAL(clicked()), this, SLOT(onBtnShowDevToolsClicked())); + connect(m_SetFocus, SIGNAL(clicked()), this, SLOT(onBtnSetFocusClicked())); + connect(m_CallJSCode, SIGNAL(clicked()), this, SLOT(onBtnCallJSCodeClicked())); + connect(m_NewBrowser, SIGNAL(clicked()), this, SLOT(onBtnNewBrowserClicked())); + connect(m_ExitAllBrowser, SIGNAL(clicked()), qApp, SLOT(quit())); + } m_Layout->addLayout(m_BrowserLayout); - m_Layout->setStretch(0,2); - m_Layout->setStretch(1,8); + m_Layout->setStretch(0, 2); + m_Layout->setStretch(1, 8); + setMinimumHeight(1000); setLayout(m_Layout); - connect(m_BtnToUrl, &QPushButton::clicked, this, &CefWidget::onBtnToUrl); - connect(m_DevTools, &QPushButton::clicked, this, &CefWidget::onBtnShowDevToolsClicked); - connect(m_SetFocus, &QPushButton::clicked, this, &CefWidget::onBtnSetFocusClicked); - connect(m_CallJSCode, &QPushButton::clicked, this, &CefWidget::onBtnCallJSCodeClicked); - connect(m_NewBrowser, &QPushButton::clicked, this, &CefWidget::onBtnNewBrowserClicked); - connect(m_ExitAllBrowser, &QPushButton::clicked, qApp, &QCoreApplication::quit); - setMinimumSize(1000, 800); initBrowser(); } -CefWidget::~CefWidget() {} +CefWidget::~CefWidget() +{ +} void CefWidget::initBrowser() { @@ -58,7 +66,7 @@ void CefWidget::initBrowser() m_CefWidget->deleteLater(); m_CefWidget = nullptr; } - setting.setHardwareAcceleration(true); + // setting.setHardwareAcceleration(true); m_CefWidget = new CefViewWidget("https://www.bilibili.com/", &setting, this); connect(m_CefWidget, &QCefView::invokeMethod, this, &CefWidget::onInvokeMethod); connect(m_CefWidget, &QCefView::cefUrlRequest, this, &CefWidget::onQCefUrlRequest); @@ -69,6 +77,24 @@ void CefWidget::initBrowser() connect(m_CefWidget, &QCefView::loadError, this, &CefWidget::onLoadError); m_BrowserLayout->addWidget(m_CefWidget); } +void CefWidget::toString(QString str){ + m_CefWidget->navigateToString(str); +} +void CefWidget::onBtnToString() +{ + QString html = QDir::currentPath() + "/html/4b7c4898-2d2b-447b-a549-03e8727ae1e6.html"; + QFile file(html); + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + qDebug() << "无法打开文件"; + } + QString str = QString::fromStdString(file.readAll().toStdString()); + file.close(); + if (!str.isEmpty()) + { + m_CefWidget->navigateToString(str); + } +} void CefWidget::onBtnToUrl() { @@ -79,9 +105,9 @@ void CefWidget::onBtnToUrl() } void CefWidget::onInvokeMethod(const QCefBrowserId &browserId, - const QCefFrameId &frameId, - const QString &method, - const QVariantList &arguments) + const QCefFrameId &frameId, + const QString &method, + const QVariantList &arguments) { // extract the arguments and dispatch the invocation to corresponding handler if (0 == method.compare("TestMethod")) @@ -142,16 +168,15 @@ void CefWidget::onQCefQueryRequest(const QCefBrowserId &browserId, const QCefFra } void CefWidget::onJavascriptResult(const QCefBrowserId &browserId, - const QCefFrameId &frameId, - const QString &context, - const QVariant &result) + const QCefFrameId &frameId, + const QString &context, + const QVariant &result) { auto jsonValue = QJsonDocument::fromVariant(result); auto jsonString = QString(jsonValue.toJson()); QString title("Javascript result notification"); QString text = QString("Context: %1\r\nResult in JSON format:\r\n%2").arg(context).arg(jsonString); - QMessageBox::information(this->window(), title, text); } @@ -162,9 +187,9 @@ void CefWidget::onLoadingStateChanged(const QCefBrowserId &browserId, bool isLoa } void CefWidget::onLoadStart(const QCefBrowserId &browserId, - const QCefFrameId &frameId, - bool isMainFrame, - int transitionType) + const QCefFrameId &frameId, + bool isMainFrame, + int transitionType) { qDebug() << "onLoadStart, browserId:" << browserId << ", frameId:" << frameId << ", isMainFrame:" << isMainFrame << ", transitionType:" << transitionType; @@ -177,11 +202,11 @@ void CefWidget::onLoadEnd(const QCefBrowserId &browserId, const QCefFrameId &fra } void CefWidget::onLoadError(const QCefBrowserId &browserId, - const QCefFrameId &frameId, - bool isMainFrame, - int errorCode, - const QString &errorMsg, - const QString &failedUrl) + const QCefFrameId &frameId, + bool isMainFrame, + int errorCode, + const QString &errorMsg, + const QString &failedUrl) { qDebug() << "onLoadError, browserId:" << browserId << ", frameId:" << frameId << ", isMainFrame:" << isMainFrame << ", errorCode:" << errorCode; diff --git a/src/QCefWidget/CefWidget.h b/src/QCefWidget/CefWidget.h index 3f289e5..36f7859 100644 --- a/src/QCefWidget/CefWidget.h +++ b/src/QCefWidget/CefWidget.h @@ -18,6 +18,7 @@ public: ~CefWidget(); private: void initBrowser(); + void toString(QString str); private: QVBoxLayout* m_Layout={}; QHBoxLayout* m_OptionsLayout={}; @@ -29,9 +30,10 @@ private: QPushButton* m_SetFocus={}; QLineEdit* m_TextToUrl={}; QPushButton* m_BtnToUrl={}; + QPushButton* m_BtnToString={}; QCefView* m_CefWidget ={}; QCefSetting setting; - + bool DevMode=true; protected: void createLeftCefView(); // QCefView slots @@ -55,14 +57,14 @@ protected slots: int errorCode, const QString& errorMsg, const QString& failedUrl); - //ui slots protected slots: void onBtnShowDevToolsClicked(); void onBtnSetFocusClicked(); void onBtnCallJSCodeClicked(); void onBtnNewBrowserClicked(); - +public slots: + void onBtnToString(); void onBtnToUrl(); }; diff --git a/src/ctaiHistoryTextEdit.cpp b/src/ctaiHistoryTextEdit.cpp index b1583c6..81dec5f 100644 --- a/src/ctaiHistoryTextEdit.cpp +++ b/src/ctaiHistoryTextEdit.cpp @@ -14,7 +14,7 @@ void ctaiHistoryTextEdit::initLayout(msg_type msg_type_mode) main_layout = new QVBoxLayout(); initMsgLine(); initMsgHeaderLayout(msg_type_mode); - initMsgHistoryLayout(); + initMsgHistoryLayout(msg_type_mode); // 主布局 main_layout->addLayout(header_layout); main_layout->addLayout(history_layout); @@ -34,12 +34,11 @@ void ctaiHistoryTextEdit::initMsgLine() msg_line->setFrameShadow(QFrame::Sunken); // 凹陷效果 msg_line->setLineWidth(2); // 线宽 } -void ctaiHistoryTextEdit::initMsgHistoryLayout() +void ctaiHistoryTextEdit::initMsgHistoryLayout(msg_type msg_type_mode) { history_layout = new QVBoxLayout(); // 历史信息QTextEdit m_msg_history = new QTextEdit(); - m_cef_widget=new CefWidget(); m_math_convert = new ctaiMathConvert(); m_msg_history->setUndoRedoEnabled(false); // 关闭撤销历史以节省内存 m_msg_history->setAcceptRichText(true); @@ -47,7 +46,15 @@ void ctaiHistoryTextEdit::initMsgHistoryLayout() m_msg_history->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); m_msg_history->setObjectName("m_msg_history"); m_msg_history->setReadOnly(true); - history_layout->addWidget(m_cef_widget); + if (msg_type_mode == SYSTEM) + { + m_cef_widget = new CefWidget(); + history_layout->addWidget(m_cef_widget); + } + else + { + history_layout->addWidget(m_msg_history); + } history_layout->addWidget(msg_line); history_layout->setContentsMargins(0, 0, 0, 0); } @@ -81,10 +88,10 @@ void ctaiHistoryTextEdit::initMsgHeaderLayout(msg_type msg_type_mode) header_info_layout->addWidget(m_msg_header); header_info_layout->setContentsMargins(0, 0, 0, 0); // 2.SYSTEM消息头水平右信息区 - m_msg_tokens = new QPushButton(); + m_msg_tokens = new QPushButton(); m_msg_tokens->setObjectName("m_msg_tokens"); header_info_layout->addWidget(m_msg_fold); - header_info_layout->addWidget(m_history_to_send); + header_info_layout->addWidget(m_history_to_send); header_info_layout->addWidget(m_restart_to_send); header_info_layout->addWidget(m_msg_tokens); header_info_layout->addWidget(m_msg_delete); @@ -100,7 +107,7 @@ void ctaiHistoryTextEdit::initMsgHeaderLayout(msg_type msg_type_mode) m_msg_user_header_ico = new QPushButton(); m_msg_user_header_ico->setObjectName("m_msg_system_header_ico"); header_info_layout->addWidget(m_msg_user_header_ico); - header_info_layout->addWidget(m_msg_header); + header_info_layout->addWidget(m_msg_header); header_info_layout->addWidget(m_msg_fold); header_info_layout->addWidget(m_history_to_send); header_info_layout->addWidget(m_restart_to_send); @@ -116,31 +123,31 @@ void ctaiHistoryTextEdit::set_default_opts() void ctaiHistoryTextEdit::connect_signals(msg_type msg_type_mode) { if (msg_type_mode == SYSTEM) - { - //复制功能 + { + // 复制功能 connect(m_msg_tools, SIGNAL(signalsOnCopy()), this, SLOT(slotsOnCopy())); - //tokens显示功能 + // tokens显示功能 connect(m_msg_tokens, SIGNAL(clicked()), this, SLOT(slotsOnTokens())); - //显示模式功能 + // 显示模式功能 connect(m_msg_tools, SIGNAL(signalsDisplayMode(QString)), this, SLOT(slotsOnDisplay(QString))); - //字体大小功能 + // 字体大小功能 connect(m_msg_tools, SIGNAL(signalsDisplayFontSize()), this, SLOT(slotsOnDisplayFontSize())); - //浏览器功能 + // 浏览器功能 connect(m_msg_tools, SIGNAL(signalsSendBrowser()), this, SLOT(slotsOnSendBrowser())); - //保存菜单功能 + // 保存菜单功能 connect(m_msg_tools, SIGNAL(signalsSaveFile(QString, int)), this, SLOT(slotsOnSave(QString, int))); // 其他功能菜单 connect(m_msg_tools, SIGNAL(signalsOnOptsMenu()), this, SLOT(slotsOnOptsMenu())); } - //删除信息 + // 删除信息 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 + // 插入msg到send connect(m_history_to_send, SIGNAL(clicked()), this, SLOT(slotsHisResToSend())); - //重试send + // 重试send connect(m_restart_to_send, SIGNAL(clicked()), this, SLOT(slotsHisResToSend())); } void ctaiHistoryTextEdit::slotsHisResToSend() @@ -200,7 +207,7 @@ void ctaiHistoryTextEdit::slotsOnSave(QString save_path, int index) temp_current_content = m_msg_history->toPlainText(); break; case 1: - temp_current_content = m_msg_history->toHtml(); + temp_current_content = m_math_convert->markdown_to_html(m_current_content); break; case 2: temp_current_content = m_msg_history->toMarkdown(); @@ -234,7 +241,7 @@ void ctaiHistoryTextEdit::slotsOnDisplay(QString mode) } else if (mode == "HTML渲染" || mode == "Markdown渲染") { - m_msg_history->setHtml(m_math_convert->replace_tags_svg(m_current_content, m_msg_tools->getFontSize().toInt())); + m_msg_history->setHtml(m_math_convert->markdown_to_rich(m_current_content, m_msg_tools->getFontSize().toInt())); QTextDocument *doc = m_msg_history->document(); doc->adjustSize(); } @@ -337,7 +344,7 @@ void ctaiHistoryTextEdit::addSystemMessage(const model_data &message) // 非流式模式直接设置全部内容 m_current_content = QSL(message.postback_model_data); } - + m_msg_history->setMarkdown(m_current_content); } // 增加tokens信息 diff --git a/src/ctaiHistoryTextEdit.h b/src/ctaiHistoryTextEdit.h index 8619198..813a0c6 100644 --- a/src/ctaiHistoryTextEdit.h +++ b/src/ctaiHistoryTextEdit.h @@ -47,7 +47,7 @@ public: ~ctaiHistoryTextEdit(); void initLayout(msg_type msg_type_mode); void initMsgHeaderLayout(msg_type msg_type_mode); - void initMsgHistoryLayout(); + void initMsgHistoryLayout(msg_type msg_type_mode); void initMsgLine(); void addUserMessage(const model_data &message); void addSystemMessage(const model_data &message); diff --git a/src/ctaiMathConvert.cpp b/src/ctaiMathConvert.cpp index 8a0216e..c3d95ef 100644 --- a/src/ctaiMathConvert.cpp +++ b/src/ctaiMathConvert.cpp @@ -109,12 +109,13 @@ QString ctaiMathConvert::replace_tags_svg(const QString &text, int font_size) const auto &rep = replacements[i]; result.replace(rep.first, rep.second, svgResults[i]); } - return markdown_to_html(result); + return result; } -QString ctaiMathConvert::markdown_to_html(const QString &text) +QString ctaiMathConvert::markdown_to_rich(const QString &text,int font_size) { + QString markdown_svg_html=replace_tags_svg(text,font_size); // 转换为UTF-8编码的字符串 - QByteArray markdown = text.toUtf8(); + QByteArray markdown = markdown_svg_html.toUtf8(); // 启用所有 GFM 扩展选项 int options = CMARK_OPT_SOURCEPOS | @@ -137,7 +138,7 @@ QString ctaiMathConvert::markdown_to_html(const QString &text) print_ast_node(doc, 0); } // 转换为HTML - char *html = cmark_render_html(doc, options, NULL); + char *html = cmark::cmark_render_html(doc, options, NULL); QString result = QString::fromUtf8(html); replace_symbol(result); // 释放内存 @@ -146,6 +147,19 @@ QString ctaiMathConvert::markdown_to_html(const QString &text) replace_css(result); return fix_img_str_line_height(result.toUtf8()); } +QString ctaiMathConvert::markdown_to_html(const QString& str) { + QString result = str; + + // 处理LaTeX公式的转义字符 + result.replace("\\(", "\\\\("); + result.replace("\\)", "\\\\)"); + result.replace("\\[", "\\\\["); + result.replace("\\]", "\\\\]"); + result.replace("\\{", "\\\\{"); + result.replace("\\}", "\\\\}"); + + return result; +} void ctaiMathConvert::replace_css(QString& context){ context.replace("