From d12945f7b4f65a837c7a1a9ba2bf582984d49306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=89=E5=AE=87=E6=B8=85=E9=9F=B3?= <2422523675@qq.com> Date: Sun, 31 Dec 2023 17:38:12 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E6=8B=BC=E6=8E=A5=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E7=9A=84=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/workspace.xml | 30 +++++++-------- DockPanel.py | 3 +- Manager.py | 89 +++++++++++++++++++++++++++++---------------- SplitPanel.py | 7 +++- 4 files changed, 76 insertions(+), 53 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 3e53c31..b72bede 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -6,6 +6,7 @@ + @@ -30,12 +31,12 @@ - { + "lastFilter": { + "state": "OPEN", + "assignee": "heisehuanyin" } -}]]> +} - - - - - file://$PROJECT_DIR$/Manager.py - 126 - - - - \ No newline at end of file diff --git a/DockPanel.py b/DockPanel.py index c780d98..28b9eb7 100644 --- a/DockPanel.py +++ b/DockPanel.py @@ -91,6 +91,7 @@ class DockPanel(QWidget): self.can_close = True DragManager.instance().register_dockpanel(self) + self.destroyed.connect(lambda :DragManager.instance().remove_dockpanel(self)) pass def reset_parent_res(self, pinst): @@ -109,8 +110,6 @@ class DockPanel(QWidget): drag_trans.setHotSpot(QPoint(5,5)) drag_trans.exec() - def __del__(self): - DragManager.instance().remove_dockpanel(self) def sync_status(self): self.drag_header.setVisible(self.default_header) diff --git a/Manager.py b/Manager.py index 9da0e2d..ccc19c2 100644 --- a/Manager.py +++ b/Manager.py @@ -1,17 +1,17 @@ -from PyQt5.QtWidgets import QWidget, QApplication, QMainWindow +from PyQt5.QtWidgets import QWidget, QApplication, QMainWindow, QMessageBox from PyQt5.QtCore import QObject, QEvent, QRect, QMargins, Qt, QMimeData from PyQt5.QtGui import QPainter, QColor, QDragEnterEvent, QDropEvent from enum import Enum import re -class PLACE_AREA(Enum): - LEFT_AREA = 0, - RIGHT_AREA = 1, - TOP_AREA = 2, - BOTTOM_AREA = 3, - CENTER_AREA = 4, - UNDEFINE_AREA = 5, +class PlaceArea(Enum): + LeftArea = 0, + RightArea = 1, + TopArea = 2, + BottomArea = 3, + CenterArea = 4, + UndefineArea = 5, class AcceptPanel(QWidget): @@ -29,13 +29,13 @@ class AcceptPanel(QWidget): self.mgr_inst = mgr self.target_anchor :QWidget = None - self.target_area = PLACE_AREA.UNDEFINE_AREA + self.target_area = PlaceArea.UndefineArea def resizeEvent(self, a0): total_rect = self.rect() total_rect = total_rect - QMargins(5, 5, 5, 5) anchor_width = 30 - self.target_area = PLACE_AREA.UNDEFINE_AREA + self.target_area = PlaceArea.UndefineArea self.left_rect = QRect(int(total_rect.left()), int(total_rect.center().y() - anchor_width / 2), int(anchor_width), int(anchor_width)) self.right_rect = QRect(int(total_rect.right() - anchor_width), int(total_rect.center().y() - anchor_width / 2), int(anchor_width), int(anchor_width)) @@ -64,24 +64,24 @@ class AcceptPanel(QWidget): if self.left_rect.contains(a0.pos()): self.hover_rect.setWidth(int(self.hover_rect.width() / 3)) - self.target_area = PLACE_AREA.LEFT_AREA + self.target_area = PlaceArea.LeftArea elif self.right_rect.contains(a0.pos()): - self.target_area = PLACE_AREA.RIGHT_AREA + self.target_area = PlaceArea.RightArea self.hover_rect.setWidth(int(self.hover_rect.width() / 3)) self.hover_rect.moveLeft(int(self.rect().right() - self.hover_rect.width())) elif self.top_rect.contains(a0.pos()): - self.target_area = PLACE_AREA.TOP_AREA + self.target_area = PlaceArea.TopArea self.hover_rect.setHeight(int(self.hover_rect.height() / 3)) elif self.center_rect.contains(a0.pos()): - self.target_area = PLACE_AREA.CENTER_AREA + self.target_area = PlaceArea.CenterArea pass elif self.bottom_rect.contains(a0.pos()): - self.target_area = PLACE_AREA.BOTTOM_AREA + self.target_area = PlaceArea.BottomArea self.hover_rect.setHeight(int(self.hover_rect.height() / 3)) self.hover_rect.moveTop(int(self.rect().bottom() - self.hover_rect.height())) else: self.hover_rect = QRect() - self.target_area = PLACE_AREA.UNDEFINE_AREA + self.target_area = PlaceArea.UndefineArea self.update() @@ -100,55 +100,80 @@ class AcceptPanel(QWidget): from DockPanel import DockPanel view_id = result.group(1) adjust_view: DockPanel = self.mgr_inst.get_dockpanel(view_id) + abandon_frame = adjust_view.parent_res + if abandon_frame is None: + QMessageBox.critical(self, "操作无效", "视图不能与自身进行替换和拼接操作!"); + self.setVisible(False) + self.setParent(self.__peak_window(self.target_anchor)) + return + + remains_attach_frame = abandon_frame.parent_res target_view: DockPanel = self.target_anchor - if self.target_area == PLACE_AREA.CENTER_AREA and not target_view.can_replace: + if self.target_area == PlaceArea.CenterArea and not target_view.can_replace: self.setVisible(False) return - if self.target_area == PLACE_AREA.UNDEFINE_AREA: + if self.target_area == PlaceArea.UndefineArea: self.setVisible(False) return # 移除源视图 - parent_frame_rm = adjust_view.parent_res - self_siblings = parent_frame_rm.child() - if parent_frame_rm.parent_res is None: - main_window:QMainWindow = parent_frame_rm.parent() + self_siblings = abandon_frame.child() + if remains_attach_frame is None: + main_window:QMainWindow = abandon_frame.parent() views = [self_siblings[0], self_siblings[1]] views.pop(views.index(adjust_view)) main_window.setCentralWidget(views[0]) + views[0].setParent(main_window) + views[0].parent_res = None else: - pparent_frame = parent_frame_rm.parent_res if self_siblings[0] == adjust_view: - pparent_frame.replace_view(self_siblings[1], parent_frame_rm) + remains_attach_frame.replace_view(self_siblings[1], abandon_frame) else: - pparent_frame.replace_view(self_siblings[0], parent_frame_rm) + remains_attach_frame.replace_view(self_siblings[0], abandon_frame) + + abandon_frame.setParent(None) + abandon_frame.parent_res = None + del abandon_frame place_frame = target_view.parent_res - split_group:DockPanel = None # 声明类型 - if self.target_area == PLACE_AREA.LEFT_AREA: + split_group:QWidget = None # 声明类型 + if self.target_area == PlaceArea.LeftArea: split_group = SplitPanel(adjust_view, target_view, SplitType.SPLIT_H) split_group.set_split_info(SplitType.SPLIT_H, 1/3) - elif self.target_area == PLACE_AREA.RIGHT_AREA: + elif self.target_area == PlaceArea.RightArea: split_group = SplitPanel(target_view, adjust_view, SplitType.SPLIT_H) split_group.set_split_info(SplitType.SPLIT_H, 2/3) - elif self.target_area == PLACE_AREA.TOP_AREA: + elif self.target_area == PlaceArea.TopArea: split_group = SplitPanel(adjust_view, target_view, SplitType.SPLIT_V) split_group.set_split_info(SplitType.SPLIT_V, 1/3) - elif self.target_area == PLACE_AREA.BOTTOM_AREA: + elif self.target_area == PlaceArea.BottomArea: split_group = SplitPanel(target_view, adjust_view, SplitType.SPLIT_V) split_group.set_split_info(SplitType.SPLIT_V, 2/3) - elif self.target_area == PLACE_AREA.CENTER_AREA: + elif self.target_area == PlaceArea.CenterArea: split_group = adjust_view if place_frame is None: main_window = target_view.parent() - target_view.setVisible(False) main_window.setCentralWidget(split_group) + split_group.parent_res = None + target_view.setVisible(False) + self.mgr_inst.remove_dockpanel(target_view) + del target_view else: place_frame.replace_view(split_group, target_view) self.setVisible(False) + self.setParent(self.__peak_window(self.target_anchor)) + + def __peak_window(self, obj: QWidget): + if obj is None: + return None + + if obj.__class__.__name__ == "QMainWindow": + return obj + + return self.__peak_window(obj.parent()) class DragManager(QObject): diff --git a/SplitPanel.py b/SplitPanel.py index 112bb37..0bc4a70 100644 --- a/SplitPanel.py +++ b/SplitPanel.py @@ -114,8 +114,11 @@ class SplitPanel(QWidget): else: self.split_member = (self.split_member[0], new) - new.parent_res = self - new.setParent(self) + self.split_member[0].setParent(self) + self.split_member[0].parent_res = self + self.split_member[1].setParent(self) + self.split_member[1].parent_res = self + self.sync_status() self.update() pass