Встраивание нативной windows в QDockWidget - PullRequest
0 голосов
/ 24 февраля 2020

Я пытаюсь взять собственное окно из другого процесса и управлять им как виджетом закрепления в моем процессе.

Это очень похоже на: Как управлять отдельными GUI процессами в приложение Qt?

Я нашел следующее, что довольно далеко уходит: 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 big artifacts 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)

1 Ответ

0 голосов
/ 24 февраля 2020

Похоже, ключевая проблема заключалась в том, чтобы установить FramelessWindowHint windowFlag ПЕРЕД показом окна, чей hwnd будет использоваться. Тогда все, кажется, работает как ожидалось.

...