PyQt-Fluent-Widgets和QWebEngineView/vispy一起使用后导致的窗口变黑

张开发
2026/5/26 15:05:38 15 分钟阅读
PyQt-Fluent-Widgets和QWebEngineView/vispy一起使用后导致的窗口变黑
在qfluentwidgets中使用QWebEngineView加载网页或者使用vispy绘制图表会导致qfluentwidgets的window的边框变黑。(好像也有一定可能导致网页加载不出来?)def control_web(): app QApplication(sys.argv) window MSFluentWindow() this_widget QWebEngineView() this_widget.load(QUrl(https://akshare.akfamily.xyz/tutorial.html)) this_widget.setObjectName(111) window.addSubInterface(this_widget, FIF.HOME, 首页) window.show() sys.exit(app.exec()) if __name__ __main__: control_web()至于原因是两者都使用了opengl导致了冲突。qfluentwidgets本身使用了opengl绘制了窗口而QWebEngineView/vispy也使用了opengl。那么知道问题了解决办法也很简单。1.强制让qfluentwidgets使用软件渲染禁用opengl。在app创建前加上这一句。os.environ[QMLSCENE_DEVICE] softwarecontext2.又想要使用opengl渲染window又要解决问题。解决办法也是有的。使用不依靠opengl的第三方库。比如pyqtgraph代替vispy并关闭opengl(vispy出现问题后我的解决办法就是用这个)用其他不使用opengl的依赖替代QWebEngineView(没试过但是应该有用)。基本上就是确保除了qfluentwidgets外没人能用opengl3.偏要使用opengl渲染window又要opengl渲染图表/界面。即使是这种要求也是可以做到的我的朋友。解决办法就是开启一个窗口显示window。再开启一个窗口显示图表。接下来重点来了将图表窗口通过QWidget.createWindowContainer嵌入到自己的window中。两个其实是不同的窗口。但是能够在一块显示。操作起来也并不复杂。from PySide6.QtGui import QResizeEvent, QMoveEvent, QCloseEvent, QWindow from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout from PySide6.QtWebEngineWidgets import QWebEngineView from PySide6.QtCore import QUrl, QTimer, Qt from qfluentwidgets import MSFluentWindow from qfluentwidgets import FluentIcon as FIF class EmbedWebView(QWidget): 通过独立窗口 QWindow 嵌入 Web 视图解决 OpenGL 冲突 def __init__(self, url): super().__init__() self.setObjectName(111) self.setAcceptDrops(True) # 1. 创建无边框独立窗口内部包含 QWebEngineView self.web_widget QWidget() self.web_widget.setWindowFlags(Qt.FramelessWindowHint) self.web_widget.setAttribute(Qt.WA_NativeWindow) # 确保获得原生窗口句柄 web_layout QVBoxLayout(self.web_widget) web_layout.setContentsMargins(0, 0, 0, 0) self.browser QWebEngineView() web_layout.addWidget(self.browser) self.browser.load(QUrl(url)) # 2. 显示独立窗口必须先 show才能拿到有效的 winId self.web_widget.show() win_id int(self.web_widget.winId()) # 3. 根据原生窗口句柄创建 QWindow self.web_window QWindow.fromWinId(win_id) # 4. 将 QWindow 包装为 QWidget 容器并添加到当前控件布局 self.container QWidget.createWindowContainer(self.web_window, self) layout QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.container) def resizeEvent(self, event: QResizeEvent): 同步容器与独立窗口大小 super().resizeEvent(event) if hasattr(self, container): self.container.resize(event.size()) if hasattr(self, web_widget): self.web_widget.resize(event.size()) def moveEvent(self, event: QMoveEvent): 同步独立窗口位置一般不需要因为容器已经跟随父控件 super().moveEvent(event) # 可选若发现显示位置偏移可手动同步 # global_pos self.mapToGlobal(self.rect().topLeft()) # if hasattr(self, web_widget): # self.web_widget.move(global_pos) def closeEvent(self, event: QCloseEvent): 确保独立窗口随主窗口关闭 if hasattr(self, web_widget): self.web_widget.close() event.accept() def control_web(): app QApplication(sys.argv) window MSFluentWindow() this_widget EmbedWebView(https://akshare.akfamily.xyz/tutorial.html) this_widget.setFixedSize(800, 600) window.addSubInterface(this_widget, FIF.HOME, 首页) window.show() sys.exit(app.exec()) if __name__ __main__: # 备选方案同时设置环境变量 control_web()像正常的组件一样使用EmbedWebView就可以了.附:我在网上找了很多关于这个问题的资料。完全没找到pyqt太小众了还是什么原因问题最后的解决办法是拷打ai加自己调试总算弄出来了。实际上最后的组件在清除再创建过程或者其他特殊情况下是否有其他问题也不清楚。真遇到问题再说。没遇到问题就是没有问题。

更多文章