Python中如何将基于Chromium引擎的CEF嵌入PyQT窗口显示?

PyQt5 自带的 webkit/webengine 好像默认不支持 javascript。。开发 PyQt 程序的话,因为有一部分系统是以前网页版操作的,就像是不是能内嵌个浏览器引擎之类的,那就直接能用了。。
还有请教一下,PyQT 用 Table Widget 操作本地 Sqlite3 数据库性能怎么样,有这方面经验的吗。。列( Column )在 10 个以内,每个界面显示和操作的是 1000 条数据( Row ),Sqlite3 总共数据条数是 10 万以内。。
Python中如何将基于Chromium引擎的CEF嵌入PyQT窗口显示?

9 回复

NW.js 欢迎你,直接网页版就可以了


import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from PyQt5.QtCore import QTimer
import cefpython3 as cef

class CefWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.browser = None
        self.embed_browser()
        
    def embed_browser(self):
        # 设置CEF窗口句柄
        window_info = cef.WindowInfo()
        window_info.SetAsChild(int(self.winId()))
        
        # 创建浏览器实例
        self.browser = cef.CreateBrowserSync(
            window_info,
            url="https://www.baidu.com"  # 初始加载页面
        )
        
    def closeEvent(self, event):
        # 关闭时清理CEF资源
        if self.browser:
            self.browser.CloseBrowser()
            self.browser = None
        cef.Shutdown()
        event.accept()

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("PyQt5 + CEF 嵌入式浏览器")
        self.setGeometry(100, 100, 1024, 768)
        
        # 创建主布局
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        layout = QVBoxLayout(central_widget)
        layout.setContentsMargins(0, 0, 0, 0)
        
        # 添加CEF部件
        self.cef_widget = CefWidget()
        layout.addWidget(self.cef_widget)
        
        # 初始化CEF
        self.init_cef()
        
    def init_cef(self):
        # CEF初始化设置
        settings = {
            "multi_threaded_message_loop": False,
            "external_message_pump": True,
            "windowless_rendering_enabled": False
        }
        cef.Initialize(settings=settings)
        
        # 定时器处理CEF消息循环
        self.timer = QTimer()
        self.timer.timeout.connect(self.cef_message_loop)
        self.timer.start(10)
        
    def cef_message_loop(self):
        cef.MessageLoopWork()
        
    def closeEvent(self, event):
        # 停止定时器
        self.timer.stop()
        super().closeEvent(event)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

核心要点:

  1. 窗口句柄传递:通过SetAsChild(int(self.winId()))将PyQt窗口句柄传递给CEF
  2. 消息循环集成:使用QTimer定时调用cef.MessageLoopWork()处理CEF事件
  3. 资源管理:在关闭时正确清理CEF浏览器实例并调用cef.Shutdown()

依赖安装:

pip install PyQt5 cefpython3

注意: CEFPython3需要对应版本的CEF二进制文件,首次运行会自动下载。

一句话建议:确保CEF消息循环与PyQt事件循环正确集成是关键。

用 table view

pyqt 的支持 js 啊

PyQt5 的 webengine 默认已经开启 java scrpit 支持了的

你看一下是不是程序里面自己关掉了。
Qt 的 webengine 讲道理也是基于 Chromium 内核的。
table widget 支持只加载需要显示的数据,具体需要自己开发实现。

我搞过简单的 C++ CEF 项目,应该是可以实现的。最简单的话,就直接把 CEF 窗口嵌进主窗口里面。复杂点的弄离屏渲染,然后画到窗口上。

实测 pyqt5 的 webengine 默认支持 javascript

这个数据量 QTableWidget 控件还是刚得住的

回到顶部