Compare commits
10 Commits
c878240d9e
...
b75d2f4d93
Author | SHA1 | Date |
---|---|---|
|
b75d2f4d93 | |
|
6dbeaf3837 | |
|
fdf57c51fd | |
|
6c39e2d295 | |
|
113e244448 | |
|
a7f701375e | |
|
847ca2f002 | |
|
d12945f7b4 | |
|
f7223984aa | |
|
108d307ccd |
|
@ -4,11 +4,9 @@
|
|||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="55c45e43-6fd9-4244-902d-86f83a348f5b" name="Changes" comment="">
|
||||
<list default="true" id="55c45e43-6fd9-4244-902d-86f83a348f5b" name="Changes" comment="pycharm配置更新">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/DockPanel.py" beforeDir="false" afterPath="$PROJECT_DIR$/DockPanel.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Manager.py" beforeDir="false" afterPath="$PROJECT_DIR$/Manager.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/SplitPanel.py" beforeDir="false" afterPath="$PROJECT_DIR$/SplitPanel.py" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
|
@ -23,11 +21,34 @@
|
|||
</option>
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="PUSH_TAGS">
|
||||
<GitPushTagMode>
|
||||
<option name="argument" value="--tags" />
|
||||
<option name="title" value="All" />
|
||||
</GitPushTagMode>
|
||||
</option>
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="GitHubPullRequestSearchHistory">{
|
||||
"lastFilter": {
|
||||
"state": "OPEN",
|
||||
"assignee": "heisehuanyin"
|
||||
}
|
||||
}</component>
|
||||
<component name="GithubPullRequestsUISettings">
|
||||
<option name="selectedUrlAndAccountId">
|
||||
<UrlAndAccount>
|
||||
<option name="accountId" value="e2cefb47-a99c-4e4b-bae0-586cfe078ae3" />
|
||||
<option name="url" value="https://github.com/heisehuanyin/QDragsView.git" />
|
||||
</UrlAndAccount>
|
||||
</option>
|
||||
</component>
|
||||
<component name="HierarchyBrowserManager">
|
||||
<option name="IS_AUTOSCROLL_TO_SOURCE" value="true" />
|
||||
</component>
|
||||
<component name="MarkdownSettingsMigration">
|
||||
<option name="stateVersion" value="1" />
|
||||
</component>
|
||||
<component name="ProjectColorInfo">{
|
||||
"associatedIndex": 2
|
||||
}</component>
|
||||
|
@ -39,20 +60,20 @@
|
|||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
"Python.DockPanel.executor": "Debug",
|
||||
"Python.Manager.executor": "Run",
|
||||
"Python.SplitPanel.executor": "Run",
|
||||
"Python.Widget.executor": "Run",
|
||||
"Python.test.executor": "Run",
|
||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
||||
"git-widget-placeholder": "main",
|
||||
"settings.editor.selected.configurable": "preferences.sourceCode"
|
||||
<component name="PropertiesComponent">{
|
||||
"keyToString": {
|
||||
"Python.DockPanel.executor": "Debug",
|
||||
"Python.Manager.executor": "Run",
|
||||
"Python.SplitPanel.executor": "Run",
|
||||
"Python.Widget.executor": "Run",
|
||||
"Python.test.executor": "Run",
|
||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
||||
"git-widget-placeholder": "main",
|
||||
"settings.editor.selected.configurable": "inlay.hints"
|
||||
}
|
||||
}]]></component>
|
||||
}</component>
|
||||
<component name="RunManager" selected="Python.SplitPanel">
|
||||
<configuration name="DockPanel" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||
<module name="SimpleIDE" />
|
||||
|
@ -114,7 +135,7 @@
|
|||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/SplitPanel.py" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||
<option name="EMULATE_TERMINAL" value="false" />
|
||||
<option name="EMULATE_TERMINAL" value="true" />
|
||||
<option name="MODULE_MODE" value="false" />
|
||||
<option name="REDIRECT_INPUT" value="false" />
|
||||
<option name="INPUT_FILE" value="" />
|
||||
|
@ -142,6 +163,12 @@
|
|||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<list>
|
||||
<item itemvalue="Python.DockPanel" />
|
||||
<item itemvalue="Python.Manager" />
|
||||
<item itemvalue="Python.SplitPanel" />
|
||||
<item itemvalue="Python.test" />
|
||||
</list>
|
||||
<recent_temporary>
|
||||
<list>
|
||||
<item itemvalue="Python.SplitPanel" />
|
||||
|
@ -167,6 +194,63 @@
|
|||
<option name="presentableId" value="Default" />
|
||||
<updated>1703843144486</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00001" summary="删除冗余打印代码">
|
||||
<option name="closed" value="true" />
|
||||
<created>1703944526835</created>
|
||||
<option name="number" value="00001" />
|
||||
<option name="presentableId" value="LOCAL-00001" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1703944526835</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00002" summary="基本拼接功能的实现">
|
||||
<option name="closed" value="true" />
|
||||
<created>1704015498724</created>
|
||||
<option name="number" value="00002" />
|
||||
<option name="presentableId" value="LOCAL-00002" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1704015498724</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00003" summary="添加图片">
|
||||
<option name="closed" value="true" />
|
||||
<created>1704016704879</created>
|
||||
<option name="number" value="00003" />
|
||||
<option name="presentableId" value="LOCAL-00003" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1704016704879</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00004" summary="更新README">
|
||||
<option name="closed" value="true" />
|
||||
<created>1704017038264</created>
|
||||
<option name="number" value="00004" />
|
||||
<option name="presentableId" value="LOCAL-00004" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1704017038264</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00005" summary="pycharm配置更新">
|
||||
<option name="closed" value="true" />
|
||||
<created>1704024507110</created>
|
||||
<option name="number" value="00005" />
|
||||
<option name="presentableId" value="LOCAL-00005" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1704024507110</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00006" summary="pycharm配置更新">
|
||||
<option name="closed" value="true" />
|
||||
<created>1704194851950</created>
|
||||
<option name="number" value="00006" />
|
||||
<option name="presentableId" value="LOCAL-00006" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1704194851950</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="7" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="VcsManagerConfiguration">
|
||||
<MESSAGE value="删除冗余打印代码" />
|
||||
<MESSAGE value="基本拼接功能的实现" />
|
||||
<MESSAGE value="添加图片" />
|
||||
<MESSAGE value="更新README" />
|
||||
<MESSAGE value="pycharm配置更新" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="pycharm配置更新" />
|
||||
</component>
|
||||
</project>
|
10
DockPanel.py
10
DockPanel.py
|
@ -32,12 +32,12 @@ class DragHeader(QFrame):
|
|||
|
||||
self.min_button=QPushButton("-")
|
||||
self.min_button.clicked.connect(lambda : self.retrieve_request[QWidget].emit(parent))
|
||||
self.min_button.setMaximumSize(22,22)
|
||||
self.min_button.setMinimumSize(22,22)
|
||||
self.min_button.setMaximumSize(22,22)
|
||||
self.layout_inst.addWidget(self.min_button,stretch=0, alignment=Qt.AlignRight)
|
||||
self.close_button=QPushButton("x")
|
||||
self.close_button.clicked.connect(lambda : self.close_request[QWidget].emit(parent))
|
||||
self.close_button.setMaximumSize(22,22)
|
||||
self.close_button.setMinimumSize(22,22)
|
||||
self.close_button.setMaximumSize(22,22)
|
||||
self.layout_inst.addWidget(self.close_button, stretch=0, alignment=Qt.AlignRight)
|
||||
pass
|
||||
|
@ -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,15 +110,10 @@ 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)
|
||||
|
||||
def paintEvent(self, a0):
|
||||
super(DockPanel, self).paintEvent(a0)
|
||||
print(self.windowTitle() + "::" + str(self.isVisible()))
|
||||
|
||||
if __name__ == "__main__":
|
||||
app=QApplication([])
|
||||
|
|
98
Manager.py
98
Manager.py
|
@ -1,9 +1,19 @@
|
|||
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 PlaceArea(Enum):
|
||||
LeftArea = 0,
|
||||
RightArea = 1,
|
||||
TopArea = 2,
|
||||
BottomArea = 3,
|
||||
CenterArea = 4,
|
||||
UndefineArea = 5,
|
||||
|
||||
|
||||
class AcceptPanel(QWidget):
|
||||
|
||||
def __init__(self, mgr):
|
||||
|
@ -19,11 +29,13 @@ class AcceptPanel(QWidget):
|
|||
|
||||
self.mgr_inst = mgr
|
||||
self.target_anchor :QWidget = None
|
||||
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 = 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))
|
||||
|
@ -47,24 +59,29 @@ class AcceptPanel(QWidget):
|
|||
painter.fillRect(self.right_rect, Qt.green)
|
||||
painter.fillRect(self.center_rect, Qt.green)
|
||||
|
||||
def mouseMoveEvent(self, a0):
|
||||
def dragMoveEvent(self, a0):
|
||||
self.hover_rect = self.rect()
|
||||
print(a0.pos())
|
||||
|
||||
if self.left_rect.contains(a0.pos()):
|
||||
self.hover_rect.setWidth(int(self.hover_rect.width() / 3))
|
||||
self.target_area = PlaceArea.LeftArea
|
||||
elif self.right_rect.contains(a0.pos()):
|
||||
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 = PlaceArea.TopArea
|
||||
self.hover_rect.setHeight(int(self.hover_rect.height() / 3))
|
||||
elif self.center_rect.contains(a0.pos()):
|
||||
self.target_area = PlaceArea.CenterArea
|
||||
pass
|
||||
elif self.bottom_rect.contains(a0.pos()):
|
||||
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 = PlaceArea.UndefineArea
|
||||
|
||||
self.update()
|
||||
|
||||
|
@ -79,27 +96,84 @@ class AcceptPanel(QWidget):
|
|||
regex = re.compile("view-drags\\(([^\\(\\)]+)\\)")
|
||||
result = regex.match(a0.mimeData().text())
|
||||
if result:
|
||||
from SplitPanel import SplitPanel, SplitType
|
||||
from DockPanel import DockPanel
|
||||
view_id = result.group(1)
|
||||
adjust_view = self.mgr_inst.get_dockpanel(view_id)
|
||||
target_view = self.target_anchor
|
||||
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 == PlaceArea.CenterArea and not target_view.can_replace:
|
||||
self.setVisible(False)
|
||||
return
|
||||
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: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 == 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 == 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 == 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 == PlaceArea.CenterArea:
|
||||
split_group = adjust_view
|
||||
|
||||
if place_frame is None:
|
||||
main_window = target_view.parent()
|
||||
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):
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# QDragsView
|
||||
## 开发目标
|
||||
1. 完成一个拖拽式拼接视图类库,模拟VS视图的部分功能
|
||||
2. 使用Python语言完成
|
||||
|
||||
## 开发环境
|
||||
1. PyQt5
|
||||
2. Python3.12
|
||||
3. PyCharm
|
||||
4. Win10
|
||||
|
||||
## 图片
|
||||

|
||||
初始示例界面
|
||||
|
||||
|
||||

|
||||
调整后的界面
|
||||
|
||||
|
||||

|
||||
削减视图数量后界面
|
|
@ -1,4 +1,4 @@
|
|||
import Manager
|
||||
from Manager import DragManager
|
||||
from DockPanel import DockPanel
|
||||
from PyQt5.QtWidgets import QApplication, QWidget, QFrame
|
||||
from enum import Enum
|
||||
|
@ -87,10 +87,6 @@ class SplitPanel(QWidget):
|
|||
self.split_member[1].setVisible(True)
|
||||
pass
|
||||
|
||||
def paintEvent(self, a0):
|
||||
super(SplitPanel, self).paintEvent(a0)
|
||||
print(self.split_member[0].windowTitle() + "\\" + self.split_member[1].windowTitle())
|
||||
|
||||
def child(self):
|
||||
return self.split_member[0], self.split_member[1], self.split_info[0]
|
||||
|
||||
|
@ -117,9 +113,12 @@ class SplitPanel(QWidget):
|
|||
self.split_member = (new, self.split_member[1])
|
||||
else:
|
||||
self.split_member = (self.split_member[0], new)
|
||||
new.parent_res = self
|
||||
new.setParent(self)
|
||||
old.setParent(None)
|
||||
|
||||
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
|
||||
|
@ -128,7 +127,7 @@ class SplitPanel(QWidget):
|
|||
if __name__ == "__main__":
|
||||
app = QApplication([])
|
||||
ow = QMainWindow()
|
||||
app.installEventFilter(Manager.DragManager.instance())
|
||||
app.installEventFilter(DragManager.instance())
|
||||
|
||||
a = DockPanel("docka", None, None)
|
||||
b = DockPanel("dockb", None, None)
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 6.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.3 KiB |
Loading…
Reference in New Issue