Я создал систему обмена сообщениями, которая позволяет мне создавать windows из отдельных процессов в одном приложении.
Для этого я создал ProxyWidget, который наследуется от QDockWidget, к которому я добавляю dummy_widget.
Используя фильтр событий и другие сигналы, я отслеживаю, когда виджет перемещается и изменяет размеры. Затем я отправляю обновления размера ведомому приложению, которое помещает безрамное окно поверх того, где должно быть содержимое дока.
Это начинает работать довольно хорошо, так как я сглаживаю все угловые случаи для различных состояний и событий дока.
У меня проблема с поиском точного размера и смещения для размещения окна. Я не могу найти системный c способ учета размера строки заголовка окна.
При плавающем поле я обнаружил, что константа +9 +32 работает с моей настройкой окна, но я уверен, что это не так portable!
При стыковке кажется, что, сдвигаясь вниз на разницу между размером dummy_widget и размером QDockWidget, я могу подойти довольно близко
class DockingWidgetProxy(QtWidgets.QDockWidget):
def __init__(self, view_setting: ViewSetting, conn:GUIClientHandler, *args, **kwargs):
super().__init__(*args, **kwargs)
self.logger = logging.getLogger('DockingProxy')
self.conn = conn
self.in_move =False
self.dummy_widget = QtWidgets.QWidget()
self.setWidget(self.dummy_widget)
self.dockLocationChanged.connect(self.on_dock_changed)
self.topLevelChanged.connect(self.on_topLevelChanged)
self.installEventFilter(self)
def eventFilter(self, obj, event):
try:
if event.type() == QtCore.QEvent.Move:
self.moveEvent(event)
elif event.type() == QtCore.QEvent.Resize:
self.resizeEvent(event)
except:
self.logger.error("failed to update geometry", exc_info=True)
return False
def resizeEvent(self, ev:QtGui.QResizeEvent):
self.logger.info(f"Proxy {self.view_settings.window_name} resized to {ev.size()}")
self.conn.resize(self.widget().size())
def moveEvent(self, event):
if self.isFloating():
# floating window is moving - send update to client
rect = self.frameGeometry()
p = rect.topLeft()
p_slave = QtCore.QPoint()
p_slave.setX(p.x()+9) # <------------how to remove this hard code!!!!
p_slave.setY(p.y()+32)
self.conn.move(p_slave)
self.logger.debug('move floating')
else:
ws = self.dummy_widget.size()
ps = self.size()
c = QtCore.QPoint(ps.width() - ws.width(),(ps.height() - ws.height())) # <- this is not quite right
p = self.mapToGlobal(c)
self.logger.info(f"Docked Move {self.view_settings.window_name} moved to {p}")
self.conn.move(p)
def main_window_move(self):
if not self.isFloating():
ws = self.dummy_widget.size()
ps = self.size()
c = QtCore.QPoint(ps.width() - ws.width(), (ps.height() - ws.height()))# <- this is not quite right
p = self.mapToGlobal(c)
self.logger.info(f"Docked Move {self.view_settings.window_name} moved to {p}")
self.conn.move(p)
Я выделил несоответствие ниже. Несоответствие смещается немного, иногда больше, иногда меньше, когда перемещаются ручки док-станции.