【发布时间】:2021-04-25 05:42:33
【问题描述】:
我正在使用PySide2.QtGui.QWindow.fromWinId(windowId) 将另一个窗口嵌入到Qt 小部件中。它工作得很好,但是当原始 X11 窗口破坏它时它不会触发事件。
如果我使用mousepad & python3 embed.py 运行下面的文件并按Ctrl+Q,则不会触发任何事件,我只剩下一个空小部件。
如何检测QWindow.fromWinId导入的X11窗口何时被其创建者销毁?
#!/usr/bin/env python
# sudo apt install python3-pip
# pip3 install PySide2
import sys, subprocess, PySide2
from PySide2 import QtGui, QtWidgets, QtCore
class MyApp(QtCore.QObject):
def __init__(self):
super(MyApp, self).__init__()
# Get some external window's windowID
print("Click on a window to embed it")
windowIdStr = subprocess.check_output(['sh', '-c', """xwininfo -int | sed -ne 's/^.*Window id: \\([0-9]\\+\\).*$/\\1/p'"""]).decode('utf-8')
windowId = int(windowIdStr)
print("Embedding window with windowId=" + repr(windowId))
# Create a simple window frame
self.app = QtWidgets.QApplication(sys.argv)
self.mainWindow = QtWidgets.QMainWindow()
self.mainWindow.show()
# Grab the external window and put it inside our window frame
self.externalWindow = QtGui.QWindow.fromWinId(windowId)
self.externalWindow.setFlags(QtGui.Qt.FramelessWindowHint)
self.container = QtWidgets.QWidget.createWindowContainer(self.externalWindow)
self.mainWindow.setCentralWidget(self.container)
# Install event filters on all Qt objects
self.externalWindow.installEventFilter(self)
self.container.installEventFilter(self)
self.mainWindow.installEventFilter(self)
self.app.installEventFilter(self)
self.app.exec_()
def eventFilter(self, obj, event):
# Lots of events fire, but no the Close one
print(str(event.type()))
if event.type() == QtCore.QEvent.Close:
mainWindow.close()
return False
prevent_garbage_collection = MyApp()
【问题讨论】:
-
这是您在实际程序中启动嵌入式应用程序的方式吗?您实际上是在尝试嵌入 mousepad 还是其他一些应用程序?更现实的测试用例可能更有帮助。您还应该说明您需要在哪些平台上工作。
-
@ekhumoro 我正在嵌入多个应用程序:Inkscape、GIMP、Blender……以及至少一个文本编辑器(尽管可能不是鼠标垫),因此解决方案不应该是特定于应用程序的。我使用
Popen启动应用程序,并过滤xwininfo和xprop的输出以从PID 中获取窗口ID。完整代码在github.com/jsmaniac(还是乱码)+MyX11Utils.py同目录下 -
@ekhumoro 关于平台的要点。由于我将这些外部应用程序嵌入到适用于 Linux、Windows、BSD 和 macos 的 FreeCAD 中,因此这四个将是理想的,但仅 Linux 的 Xorg-only(没有 Wayland)将是一个好的开始。现在我唯一的选择是轮询,这很昂贵。
-
@SuzanneDupéron 虽然可以实现外部窗口嵌入,但它有 很多 问题,具体取决于平台和“版本”(MacOS/Windows 的操作系统版本,发行版/wm /dm 对于 Linux)。其中最重要的一项是键盘焦点处理,它经常会出现一些问题,因为它没有正确获取或释放;几何通常是另一个,因为取决于程序使用的框架,可能会有一些特性(甚至覆盖)假设程序的窗口是“它自己的”,这对于基于停靠小部件的程序来说也可能成为一个更大的问题,例如作为 GIMP。
标签: python python-3.x embed pyside2 qwindow