问题描述
我正在尝试从其他进程中获取本机窗口,并将其作为我的进程中的停靠小部件进行管理.
这非常类似于:
应该是这样的:
以下是控制台打印输出,指示每个组件在不同时间的大小:
原始窗口大小 PyQt5.QtCore.QSize(75, 23)fromWinId 窗口大小 PyQt5.QtCore.QSize(120, 23)windowContainer 小部件大小 PyQt5.QtCore.QSize(640, 480)停靠小部件大小 PyQt5.QtCore.QSize(640, 480)平台表面 PyQt5.QtCore.QSize(136, 62), PyQt5.QtCore.QSize(640, 480)WinIdChange PyQt5.QtCore.QSize(136, 62), PyQt5.QtCore.QSize(640, 480)WindowIconChange PyQt5.QtCore.QSize(136, 62), PyQt5.QtCore.QSize(640, 480)波兰语 PyQt5.QtCore.QSize(136, 62), PyQt5.QtCore.QSize(640, 480)移动 PyQt5.QtCore.QSize(136, 62), PyQt5.QtCore.QSize(640, 480)调整 PyQt5.QtCore.QSize(136, 62), PyQt5.QtCore.QSize(200, 100)显示 PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)CursorChange PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)ShowToParent PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)波兰请求 PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)LayoutRequest PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)更新后期 PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)更新请求 PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)WindowActivate PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)ActivationChange PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)InputMethodQuery PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)ShortcutOverride PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)按键 PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)WindowDeactivate PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)ActivationChange PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)
看起来关键问题是在显示将使用其 hwnd 的窗口之前设置 FramelessWindowHint windowFlag.然后一切似乎都按预期工作.
I am trying to take a native window from an other process and manage it as a docking widget in my process.
This is very similar to:How to manage separate GUI processes in a Qt application?
I have found the following which gets me pretty far:https://gist.github.com/torarnv/c5dfe2d2bc0c089910ce
Problem is the dock window size does not match the size of the contents it's wrapping (there is a margin which it about 15px wide and 40px tall (see pictures for examples)).
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtCore import Qt
import logging
envent_type_lookup = {v:k for k,v in QtCore.QEvent.__dict__.items() if isinstance(v, int)}
class DockingWindowProxy(QtWidgets.QDockWidget):
def __init__(self, hwnd, *args, **kwargs):
super().__init__(*args, **kwargs)
self.window_wrapper = QtGui.QWindow.fromWinId(hwnd)
print('fromWinId window size', self.window_wrapper.size())
self.window_widget = QtWidgets.QWidget.createWindowContainer(self.window_wrapper)
self.setWindowTitle("Wrapper")
print('windowContainer widget size', self.window_widget.size())
self.setWidget(self.window_widget)
print('dock widget size', self.size())
self.installEventFilter(self)
def eventFilter(self, obj, ev):
print(f"{envent_type_lookup[ev.type()]} \t {self.window_wrapper.size()}, {self.window_widget.size()}")
return False
if __name__ == '__main__':
import win32gui
logging.basicConfig(level=logging.DEBUG)
app = QtWidgets.QApplication([])
sample = QtWidgets.QPushButton("Test")
sample.show()
print('Original window size', sample.size())
w = sample.window()
hwnd = w.winId().__int__()
pw = DockingWindowProxy(hwnd)
pw.show()
app.exec_()
Results:
Should look like:
Here are the console print outputs indicating the sizes each component has at various times:
Original window size PyQt5.QtCore.QSize(75, 23)
fromWinId window size PyQt5.QtCore.QSize(120, 23)
windowContainer widget size PyQt5.QtCore.QSize(640, 480)
dock widget size PyQt5.QtCore.QSize(640, 480)
PlatformSurface PyQt5.QtCore.QSize(136, 62), PyQt5.QtCore.QSize(640, 480)
WinIdChange PyQt5.QtCore.QSize(136, 62), PyQt5.QtCore.QSize(640, 480)
WindowIconChange PyQt5.QtCore.QSize(136, 62), PyQt5.QtCore.QSize(640, 480)
Polish PyQt5.QtCore.QSize(136, 62), PyQt5.QtCore.QSize(640, 480)
Move PyQt5.QtCore.QSize(136, 62), PyQt5.QtCore.QSize(640, 480)
Resize PyQt5.QtCore.QSize(136, 62), PyQt5.QtCore.QSize(200, 100)
Show PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)
CursorChange PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)
ShowToParent PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)
PolishRequest PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)
LayoutRequest PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)
UpdateLater PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)
UpdateRequest PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)
WindowActivate PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)
ActivationChange PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)
InputMethodQuery PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)
ShortcutOverride PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)
KeyPress PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)
WindowDeactivate PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)
ActivationChange PyQt5.QtCore.QSize(200, 100), PyQt5.QtCore.QSize(200, 100)
Looks like the key issue was to set the FramelessWindowHint windowFlag BEFORE showing the window whose hwnd will be used. Then everything appears to work as expected.
这篇关于在 QDockWidget 中嵌入本机窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!