添加代码
This commit is contained in:
parent
52f5a3d7ff
commit
351b446a15
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Python 3.12" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
|
@ -0,0 +1,5 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</state>
|
||||
</component>
|
|
@ -0,0 +1,6 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Black">
|
||||
<option name="sdkName" value="Python 3.12 (SimpleIDE)" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12" project-jdk-type="Python SDK" />
|
||||
</project>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/SimpleIDE.iml" filepath="$PROJECT_DIR$/.idea/SimpleIDE.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,169 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AutoImportSettings">
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="55c45e43-6fd9-4244-902d-86f83a348f5b" name="Changes" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/.idea/codeStyles/codeStyleConfig.xml" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="FileTemplateManagerImpl">
|
||||
<option name="RECENT_TEMPLATES">
|
||||
<list>
|
||||
<option value="Python Script" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="HierarchyBrowserManager">
|
||||
<option name="IS_AUTOSCROLL_TO_SOURCE" value="true" />
|
||||
</component>
|
||||
<component name="ProjectColorInfo"><![CDATA[{
|
||||
"associatedIndex": 2
|
||||
}]]></component>
|
||||
<component name="ProjectId" id="2aDBCkoR2x9AbgMgSJixv1KIMSj" />
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="true">
|
||||
<ConfirmationsSetting value="2" id="Add" />
|
||||
</component>
|
||||
<component name="ProjectViewState">
|
||||
<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": "master",
|
||||
"settings.editor.selected.configurable": "preferences.sourceCode"
|
||||
}
|
||||
}]]></component>
|
||||
<component name="RunManager" selected="Python.Manager">
|
||||
<configuration name="DockPanel" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||
<module name="SimpleIDE" />
|
||||
<option name="ENV_FILES" value="" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs>
|
||||
<env name="PYTHONUNBUFFERED" value="1" />
|
||||
</envs>
|
||||
<option name="SDK_HOME" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="IS_MODULE_SDK" value="true" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<option name="SCRIPT_NAME" value="D:\Projects\Python\SimpleIDE\DockPanel.py" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||
<option name="EMULATE_TERMINAL" value="false" />
|
||||
<option name="MODULE_MODE" value="false" />
|
||||
<option name="REDIRECT_INPUT" value="false" />
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="Manager" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||
<module name="SimpleIDE" />
|
||||
<option name="ENV_FILES" value="" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs>
|
||||
<env name="PYTHONUNBUFFERED" value="1" />
|
||||
</envs>
|
||||
<option name="SDK_HOME" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="IS_MODULE_SDK" value="true" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/Manager.py" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||
<option name="EMULATE_TERMINAL" value="false" />
|
||||
<option name="MODULE_MODE" value="false" />
|
||||
<option name="REDIRECT_INPUT" value="false" />
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="SplitPanel" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||
<module name="SimpleIDE" />
|
||||
<option name="ENV_FILES" value="" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs>
|
||||
<env name="PYTHONUNBUFFERED" value="1" />
|
||||
</envs>
|
||||
<option name="SDK_HOME" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="IS_MODULE_SDK" value="true" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<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="MODULE_MODE" value="false" />
|
||||
<option name="REDIRECT_INPUT" value="false" />
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="test" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||
<module name="SimpleIDE" />
|
||||
<option name="ENV_FILES" value="" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs>
|
||||
<env name="PYTHONUNBUFFERED" value="1" />
|
||||
</envs>
|
||||
<option name="SDK_HOME" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="IS_MODULE_SDK" value="true" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/test.py" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||
<option name="EMULATE_TERMINAL" value="false" />
|
||||
<option name="MODULE_MODE" value="false" />
|
||||
<option name="REDIRECT_INPUT" value="false" />
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<recent_temporary>
|
||||
<list>
|
||||
<item itemvalue="Python.Manager" />
|
||||
<item itemvalue="Python.SplitPanel" />
|
||||
<item itemvalue="Python.DockPanel" />
|
||||
<item itemvalue="Python.test" />
|
||||
</list>
|
||||
</recent_temporary>
|
||||
</component>
|
||||
<component name="SharedIndexes">
|
||||
<attachedChunks>
|
||||
<set>
|
||||
<option value="bundled-python-sdk-50da183f06c8-d3b881c8e49f-com.jetbrains.pycharm.community.sharedIndexes.bundled-PC-233.13135.95" />
|
||||
</set>
|
||||
</attachedChunks>
|
||||
</component>
|
||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="55c45e43-6fd9-4244-902d-86f83a348f5b" name="Changes" comment="" />
|
||||
<created>1703843144486</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1703843144486</updated>
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,120 @@
|
|||
from PyQt5.QtWidgets import QWidget
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
from PyQt5.QtWidgets import QLabel
|
||||
from PyQt5.QtWidgets import QVBoxLayout
|
||||
from PyQt5.QtWidgets import QHBoxLayout
|
||||
from PyQt5.QtWidgets import QFrame
|
||||
from PyQt5.QtWidgets import QPushButton
|
||||
from PyQt5.QtCore import Qt, pyqtSignal
|
||||
from PyQt5.QtCore import QSize, QPoint, QMimeData
|
||||
from PyQt5.QtGui import QDrag
|
||||
from Manager import DragManager
|
||||
|
||||
|
||||
class DragHeader(QFrame):
|
||||
close_request = pyqtSignal(QWidget)
|
||||
retrieve_request = pyqtSignal(QWidget)
|
||||
adjust_request = pyqtSignal(QWidget, QPoint)
|
||||
|
||||
def __init__(self, title: str, parent: 'DockPanel'):
|
||||
super().__init__(parent)
|
||||
|
||||
self.__place_cube = parent
|
||||
self.__pressed_mark = (False, QPoint)
|
||||
|
||||
self.layout_inst = QHBoxLayout(self)
|
||||
self.layout_inst.setSpacing(0)
|
||||
self.layout_inst.setContentsMargins(0,0,0,0)
|
||||
|
||||
self.show_label=QLabel(title, self)
|
||||
self.show_label.setContentsMargins(2, 0, 0, 0)
|
||||
self.layout_inst.addWidget(self.show_label, stretch=1, alignment=Qt.AlignLeft)
|
||||
|
||||
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.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.setMaximumSize(22,22)
|
||||
self.layout_inst.addWidget(self.close_button, stretch=0, alignment=Qt.AlignRight)
|
||||
pass
|
||||
|
||||
def mousePressEvent(self, a0):
|
||||
super(DragHeader, self).mousePressEvent(a0)
|
||||
self.__pressed_mark = (True, self.__place_cube.mapToParent(a0.pos()))
|
||||
pass
|
||||
|
||||
def mouseReleaseEvent(self, a0):
|
||||
super(DragHeader, self).mouseReleaseEvent(a0)
|
||||
self.__pressed_mark = (False, QPoint())
|
||||
pass
|
||||
|
||||
def mouseMoveEvent(self, a0):
|
||||
super(DragHeader, self).mouseMoveEvent(a0)
|
||||
if self.__pressed_mark[0]:
|
||||
self.adjust_request[QWidget,QPoint].emit(self, self.__place_cube.mapToParent(a0.pos()))
|
||||
|
||||
|
||||
class DockPanel(QWidget):
|
||||
|
||||
def __init__(self, title:str, show_inst:QWidget|None, pinst:QWidget):
|
||||
super(DockPanel, self).__init__(pinst)
|
||||
|
||||
self.setMinimumSize(60, 40)
|
||||
self.setWindowTitle(title)
|
||||
self.parent_res = pinst
|
||||
|
||||
self.layout_inst = QVBoxLayout(self)
|
||||
self.layout_inst.setSpacing(0)
|
||||
self.layout_inst.setContentsMargins(0,2,0,0)
|
||||
|
||||
self.drag_header = DragHeader(title, self)
|
||||
self.layout_inst.addWidget(self.drag_header)
|
||||
self.drag_header.setMinimumHeight(26)
|
||||
self.drag_header.setMaximumHeight(26)
|
||||
self.drag_header.setFrameShape(QFrame.Shape.Panel)
|
||||
self.drag_header.setFrameShadow(QFrame.Shadow.Raised)
|
||||
self.drag_header.setLineWidth(3)
|
||||
self.drag_header.adjust_request[QWidget,QPoint].connect(self.__adjust_accept)
|
||||
|
||||
if show_inst is not None:
|
||||
self.layout_inst.addWidget(show_inst)
|
||||
else:
|
||||
self.layout_inst.addWidget(QWidget())
|
||||
|
||||
self.default_header = True
|
||||
self.can_replace = True
|
||||
self.can_retrieve = True
|
||||
self.can_close = True
|
||||
|
||||
DragManager.instance().register_dockpanel(self)
|
||||
pass
|
||||
|
||||
def reset_parent_res(self, pinst):
|
||||
self.parent_res = pinst
|
||||
|
||||
def __adjust_accept(self, view: QWidget, pt: QPoint):
|
||||
drag_trans = QDrag(self)
|
||||
mine_data = QMimeData()
|
||||
mine_data.setText("view-drags(" + str(self.__hash__()) + ")")
|
||||
drag_trans.setMimeData(mine_data)
|
||||
drag_trans.setPixmap(self.grab(self.rect()))
|
||||
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)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app=QApplication([])
|
||||
app.installEventFilter(DragManager())
|
||||
win=DockPanel("empty-window",None,None)
|
||||
win.show()
|
||||
app.exec()
|
|
@ -0,0 +1,127 @@
|
|||
from PyQt5.QtWidgets import QWidget, QApplication
|
||||
from PyQt5.QtCore import QObject, QEvent, QRect, QMargins, Qt
|
||||
from PyQt5.QtGui import QPainter, QColor
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class AcceptPanel(QWidget):
|
||||
|
||||
def __init__(self, parent):
|
||||
super(AcceptPanel, self).__init__(parent)
|
||||
self.left_rect = QRect()
|
||||
self.right_rect = QRect()
|
||||
self.top_rect = QRect()
|
||||
self.bottom_rect = QRect()
|
||||
self.center_rect = QRect()
|
||||
self.hover_rect = QRect()
|
||||
self.setMouseTracking(True)
|
||||
self.setAcceptDrops(True)
|
||||
|
||||
def resizeEvent(self, a0):
|
||||
total_rect = self.rect()
|
||||
total_rect = total_rect - QMargins(5, 5, 5, 5)
|
||||
anchor_width = 30
|
||||
|
||||
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))
|
||||
self.top_rect = QRect(int(total_rect.center().x() - anchor_width / 2), int(total_rect.top()), int(anchor_width), int(anchor_width))
|
||||
self.bottom_rect = QRect(int(total_rect.center().x() - anchor_width / 2), int(total_rect.bottom() - anchor_width), int(anchor_width), int(anchor_width))
|
||||
self.center_rect = QRect(int(total_rect.center().x() - anchor_width / 2), int(total_rect.center().y() - anchor_width / 2), int(anchor_width), int(anchor_width))
|
||||
|
||||
def async_with(self, target_view: QWidget):
|
||||
self.resize(target_view.size())
|
||||
|
||||
def paintEvent(self, a0):
|
||||
super(AcceptPanel, self).paintEvent(a0)
|
||||
painter = QPainter(self)
|
||||
painter.fillRect(self.rect(), Qt.lightGray)
|
||||
|
||||
painter.fillRect(self.hover_rect, Qt.gray)
|
||||
|
||||
painter.fillRect(self.top_rect, Qt.green)
|
||||
painter.fillRect(self.bottom_rect, Qt.green)
|
||||
painter.fillRect(self.left_rect, Qt.green)
|
||||
painter.fillRect(self.right_rect, Qt.green)
|
||||
painter.fillRect(self.center_rect, Qt.green)
|
||||
|
||||
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))
|
||||
elif self.right_rect.contains(a0.pos()):
|
||||
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.hover_rect.setHeight(int(self.hover_rect.height() / 3))
|
||||
elif self.center_rect.contains(a0.pos()):
|
||||
pass
|
||||
elif self.bottom_rect.contains(a0.pos()):
|
||||
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.update()
|
||||
|
||||
|
||||
class DragManager(QObject):
|
||||
__unique_inst: 'DragManager' = None
|
||||
|
||||
def __init__(self):
|
||||
super(DragManager, self).__init__()
|
||||
self.__dock_map = {}
|
||||
|
||||
@classmethod
|
||||
def instance(cls):
|
||||
if cls.__unique_inst is None:
|
||||
cls.__unique_inst = DragManager()
|
||||
return cls.__unique_inst
|
||||
|
||||
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())
|
||||
|
||||
def eventFilter(self, sender: QObject | None, event: QEvent | None):
|
||||
if event.type() == QEvent.Type.DragMove:
|
||||
if sender.isWindowType():
|
||||
sender.requestActivate()
|
||||
|
||||
for ip in self.__dock_map:
|
||||
view_inst: QWidget = self.get_dockpanel(ip)
|
||||
if view_inst is None:
|
||||
return False
|
||||
|
||||
gpos = sender.mapToGlobal(event.pos())
|
||||
point = view_inst.mapFromGlobal(gpos)
|
||||
if (view_inst.rect().contains(point)) and (self.__peak_window(view_inst).isActiveWindow()):
|
||||
print(view_inst.rect())
|
||||
|
||||
pass
|
||||
|
||||
return super(DragManager, self).eventFilter(sender, event)
|
||||
|
||||
def register_dockpanel(self, view):
|
||||
self.__dock_map[str(view.__hash__())] = view
|
||||
|
||||
def remove_dockpanel(self, view):
|
||||
if str(view.__hash__()) in self.__dock_map:
|
||||
self.__dock_map.pop(str(view.__hash__()))
|
||||
|
||||
def get_dockpanel(self, address: str):
|
||||
if address in self.__dock_map:
|
||||
return self.__dock_map[address]
|
||||
return None
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = QApplication([])
|
||||
accept = AcceptPanel(None)
|
||||
accept.show()
|
||||
app.exec()
|
|
@ -0,0 +1,122 @@
|
|||
import Manager
|
||||
from DockPanel import DockPanel
|
||||
from PyQt5.QtWidgets import QApplication, QWidget, QFrame
|
||||
from enum import Enum
|
||||
from PyQt5.QtCore import pyqtSignal, QPoint
|
||||
from PyQt5.QtCore import QRect, Qt
|
||||
from PyQt5.QtWidgets import QMainWindow
|
||||
|
||||
|
||||
class SplitType(Enum):
|
||||
SPLIT_H = 0
|
||||
SPLIT_V = 1
|
||||
|
||||
|
||||
class DragSplitter(QFrame):
|
||||
adjustSignal = pyqtSignal(QPoint)
|
||||
|
||||
def __init__(self, split:SplitType, parent:QWidget):
|
||||
super(DragSplitter, self).__init__(parent)
|
||||
|
||||
self.setFrameShape(QFrame.Shape.WinPanel)
|
||||
self.setFrameShadow(QFrame.Shadow.Raised)
|
||||
|
||||
if split == SplitType.SPLIT_H:
|
||||
self.setCursor(Qt.CursorShape.SplitHCursor)
|
||||
else:
|
||||
self.setCursor(Qt.CursorShape.SplitVCursor)
|
||||
|
||||
pass
|
||||
|
||||
def mouseMoveEvent(self, a0):
|
||||
super().mouseMoveEvent(a0)
|
||||
up_point = self.mapToParent(a0.pos())
|
||||
self.adjustSignal.emit(up_point)
|
||||
|
||||
|
||||
class SplitPanel(QWidget):
|
||||
def __init__(self, a: DockPanel, b: DockPanel, split: SplitType, parent:QWidget = None):
|
||||
super(SplitPanel, self).__init__(parent)
|
||||
|
||||
self.splitter_widget = DragSplitter(split, self)
|
||||
self.splitter_widget.adjustSignal[QPoint].connect(self.__splitter_adjust)
|
||||
|
||||
self.split_member = (a, b)
|
||||
self.split_member[0].setParent(self)
|
||||
self.split_member[1].setParent(self)
|
||||
|
||||
self.split_info = (split, 0.5, 7)
|
||||
self.sync_status()
|
||||
pass
|
||||
|
||||
def __view_list(self) -> [DockPanel]:
|
||||
retval: [DockPanel] = [self.split_member[0], self.split_member[1]]
|
||||
return retval
|
||||
|
||||
def set_split_info(self, o: SplitType, pos: float, width: float = 8):
|
||||
self.split_info = (o, pos, width)
|
||||
self.sync_status()
|
||||
|
||||
def sync_status(self):
|
||||
if self.split_info[0] == SplitType.SPLIT_H:
|
||||
total_width = self.width()
|
||||
width_a = total_width * self.split_info[1]
|
||||
width_b = total_width - width_a - self.split_info[2]
|
||||
|
||||
self.split_member[0].setGeometry(0, 0, int(width_a), self.height())
|
||||
self.split_member[1].setGeometry(int(width_a + self.split_info[2]), 0, int(width_b), self.height())
|
||||
|
||||
handle_rect = QRect(int(width_a), 0, int(self.split_info[2]), self.height())
|
||||
self.splitter_widget.setGeometry(handle_rect)
|
||||
else:
|
||||
total_height = self.height()
|
||||
height_a = total_height * self.split_info[1]
|
||||
height_b = total_height - height_a - self.split_info[2]
|
||||
|
||||
self.split_member[0].setGeometry(0, 0, self.width(), int(height_a))
|
||||
self.split_member[1].setGeometry(0, int(height_a + self.split_info[2]) - 1, self.width(), int(height_b) + 1)
|
||||
|
||||
handle_rect = QRect(0, int(height_a), self.width(), int(self.split_info[2]))
|
||||
self.splitter_widget.setGeometry(handle_rect)
|
||||
pass
|
||||
|
||||
def resizeEvent(self, a0):
|
||||
super().resizeEvent(a0)
|
||||
self.sync_status()
|
||||
|
||||
def __splitter_adjust(self, pos: QPoint):
|
||||
if self.split_info[0] == SplitType.SPLIT_H:
|
||||
leftw = self.split_member[0].minimumWidth()
|
||||
rightw = self.split_member[1].minimumWidth()
|
||||
if (pos.x() >= leftw) and (pos.x() <= self.width() - rightw):
|
||||
self.split_info = (self.split_info[0], pos.x() / self.width(), self.split_info[2])
|
||||
else:
|
||||
toph = self.split_member[0].minimumHeight()
|
||||
bottomh = self.split_member[1].minimumHeight()
|
||||
if (pos.y() >= toph) and (pos.y() <= self.height() - bottomh):
|
||||
self.split_info = (self.split_info[0], pos.y() / self.height(), self.split_info[2])
|
||||
self.sync_status()
|
||||
|
||||
def replace_view(self, new: DockPanel, old: DockPanel):
|
||||
if old in self.__view_list() and new not in self.__view_list():
|
||||
if self.split_member[0] == old:
|
||||
self.split_member = (new, self.split_member[1], self.split_member[2])
|
||||
else:
|
||||
self.split_member = (self.split_member[0], new, self.split_member[2])
|
||||
old.setParent(None)
|
||||
self.sync_status()
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = QApplication([])
|
||||
ow = QMainWindow()
|
||||
app.installEventFilter(Manager.DragManager.instance())
|
||||
|
||||
a = DockPanel("docka", None, None)
|
||||
b = DockPanel("dockb", None, None)
|
||||
win = SplitPanel(a, b, SplitType.SPLIT_H)
|
||||
ow.setCentralWidget(win)
|
||||
|
||||
ow.show()
|
||||
app.exec()
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue