嵌入QDockWidget内部的本机窗口

问题描述 投票:0回答:1

我正在尝试从其他进程中获取一个本机窗口,并将其作为停靠窗口小部件进行管理。

这非常类似于:How to manage separate GUI processes in a Qt application?

我发现以下内容使我很远:https://gist.github.com/torarnv/c5dfe2d2bc0c089910ce

问题是停靠窗口的大小与它要包装的内容的大小不匹配(存在大约15像素宽和40像素高的边距(请参阅示例图片)。

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_()

结果:

warapping dock widget too bigartifacts when resized down

应该看起来像:

enter image description here

这里是控制台打印输出,指示每个组件在不同时间的尺寸:

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)
python qt pyqt hwnd qdockwidget
1个回答
0
投票

看起来关键是在显示要使用其hwnd的窗口之前,先设置FramelessWindowHint windowFlag。然后一切似乎都按预期工作。

© www.soinside.com 2019 - 2024. All rights reserved.