Compare commits

..

No commits in common. "b75d2f4d933404f6de87bea2d68d4afc518f23f8" and "c878240d9eafbee4455bfae176fa2135ff04950e" have entirely different histories.

11 changed files with 45 additions and 220 deletions

View File

@ -4,9 +4,11 @@
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="55c45e43-6fd9-4244-902d-86f83a348f5b" name="Changes" comment="pycharm配置更新">
<list default="true" id="55c45e43-6fd9-4244-902d-86f83a348f5b" name="Changes" comment="">
<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" />
@ -21,34 +23,11 @@
</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">{
&quot;lastFilter&quot;: {
&quot;state&quot;: &quot;OPEN&quot;,
&quot;assignee&quot;: &quot;heisehuanyin&quot;
}
}</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">{
&quot;associatedIndex&quot;: 2
}</component>
@ -60,20 +39,20 @@
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;Python.DockPanel.executor&quot;: &quot;Debug&quot;,
&quot;Python.Manager.executor&quot;: &quot;Run&quot;,
&quot;Python.SplitPanel.executor&quot;: &quot;Run&quot;,
&quot;Python.Widget.executor&quot;: &quot;Run&quot;,
&quot;Python.test.executor&quot;: &quot;Run&quot;,
&quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;SHARE_PROJECT_CONFIGURATION_FILES&quot;: &quot;true&quot;,
&quot;git-widget-placeholder&quot;: &quot;main&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;inlay.hints&quot;
<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>
}]]></component>
<component name="RunManager" selected="Python.SplitPanel">
<configuration name="DockPanel" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="SimpleIDE" />
@ -135,7 +114,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="true" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
@ -163,12 +142,6 @@
<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" />
@ -194,63 +167,6 @@
<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>

View File

@ -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.setMinimumSize(22,22)
self.min_button.setMaximumSize(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.setMinimumSize(22,22)
self.close_button.setMaximumSize(22,22)
self.close_button.setMaximumSize(22,22)
self.layout_inst.addWidget(self.close_button, stretch=0, alignment=Qt.AlignRight)
pass
@ -91,7 +91,6 @@ 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):
@ -110,10 +109,15 @@ 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([])

View File

@ -1,19 +1,9 @@
from PyQt5.QtWidgets import QWidget, QApplication, QMainWindow, QMessageBox
from PyQt5.QtWidgets import QWidget, QApplication, QMainWindow
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):
@ -29,13 +19,11 @@ 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))
@ -59,29 +47,24 @@ class AcceptPanel(QWidget):
painter.fillRect(self.right_rect, Qt.green)
painter.fillRect(self.center_rect, Qt.green)
def dragMoveEvent(self, a0):
def mouseMoveEvent(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()
@ -96,84 +79,27 @@ 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: 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
adjust_view = self.mgr_inst.get_dockpanel(view_id)
target_view = self.target_anchor
# 移除源视图
self_siblings = abandon_frame.child()
if remains_attach_frame is None:
main_window:QMainWindow = abandon_frame.parent()
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()
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:
remains_attach_frame.replace_view(self_siblings[1], abandon_frame)
pparent_frame.replace_view(self_siblings[1], parent_frame_rm)
else:
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)
pparent_frame.replace_view(self_siblings[0], parent_frame_rm)
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):

View File

@ -1,22 +0,0 @@
# QDragsView
## 开发目标
1. 完成一个拖拽式拼接视图类库模拟VS视图的部分功能
2. 使用Python语言完成
## 开发环境
1. PyQt5
2. Python3.12
3. PyCharm
4. Win10
## 图片
![初始界面](full.png)
初始示例界面
![调整后界面](adjust.png)
调整后的界面
![削减视图后界面](reduce.png)
削减视图数量后界面

View File

@ -1,4 +1,4 @@
from Manager import DragManager
import Manager
from DockPanel import DockPanel
from PyQt5.QtWidgets import QApplication, QWidget, QFrame
from enum import Enum
@ -87,6 +87,10 @@ 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]
@ -113,12 +117,9 @@ class SplitPanel(QWidget):
self.split_member = (new, self.split_member[1])
else:
self.split_member = (self.split_member[0], new)
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
new.parent_res = self
new.setParent(self)
old.setParent(None)
self.sync_status()
self.update()
pass
@ -127,7 +128,7 @@ class SplitPanel(QWidget):
if __name__ == "__main__":
app = QApplication([])
ow = QMainWindow()
app.installEventFilter(DragManager.instance())
app.installEventFilter(Manager.DragManager.instance())
a = DockPanel("docka", None, None)
b = DockPanel("dockb", None, None)

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

BIN
full.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB