Skip to content

Commit b5b251d

Browse files
authored
Update Python Bindings (#348)
* Update Python bindings * Add X11Extras to setup.py for Linux builds * Update Python Bindings * Update Python bindings * Update Python Bindings
1 parent 0c44acc commit b5b251d

File tree

14 files changed

+931
-28
lines changed

14 files changed

+931
-28
lines changed

demo/demo.py renamed to demo/main.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,17 @@ def create_content(self):
215215
dock_widget = self.create_calendar_dock_widget()
216216
dock_widget.setTabToolTip("Tab ToolTip\nHodie est dies magna")
217217
dock_area = self.dock_manager.addDockWidget(QtAds.CenterDockWidgetArea, dock_widget, top_dock_area)
218+
# Now we create a action to test resizing of DockArea widget
219+
action = self.menuTests.addAction("Resize {}".format(dock_widget.windowTitle()))
220+
def action_triggered():
221+
splitter = QtAds.internal.findParent(QtAds.CDockSplitter, dock_area)
222+
if not splitter:
223+
return
224+
# We change the sizes of the splitter that contains the Calendar 1 widget
225+
# to resize the dock widget
226+
width = splitter.width()
227+
splitter.setSizes([width * 2/3, width * 1/3])
228+
action.triggered.connect(action_triggered)
218229

219230
# Now we add a custom button to the dock area title bar that will create
220231
# new editor widgets when clicked

examples/centralwidget/centralWidget.py renamed to examples/centralwidget/main.py

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,7 @@
1212

1313
UI_FILE = os.path.join(os.path.dirname(__file__), 'mainwindow.ui')
1414
MainWindowUI, MainWindowBase = uic.loadUiType(UI_FILE)
15-
16-
import demo_rc # pyrcc5 demo\demo.qrc -o examples\centralWidget\demo_rc.py
17-
18-
19-
def svg_icon(filename: str):
20-
'''Helper function to create an SVG icon'''
21-
# This is a workaround, because because in item views SVG icons are not
22-
# properly scaled and look blurry or pixelate
23-
icon = QIcon(filename)
24-
icon.addPixmap(icon.pixmap(92))
25-
return icon
2615

27-
2816
class MainWindow(MainWindowUI, MainWindowBase):
2917

3018
def __init__(self, parent=None):
@@ -46,27 +34,26 @@ def __init__(self, parent=None):
4634
central_dock_area.setAllowedAreas(QtAds.DockWidgetArea.OuterDockAreas)
4735

4836
# create other dock widgets
49-
file_tree = QTreeView()
50-
file_tree.setFrameShape(QFrame.NoFrame)
51-
file_model = QFileSystemModel(file_tree)
52-
file_model.setRootPath(QDir.currentPath())
53-
file_tree.setModel(file_model)
54-
data_dock_widget = QtAds.CDockWidget("File system")
55-
data_dock_widget.setWidget(file_tree)
56-
data_dock_widget.resize(150, 250)
57-
data_dock_widget.setMinimumSize(100, 250)
58-
file_area = self.dock_manager.addDockWidget(QtAds.DockWidgetArea.LeftDockWidgetArea, data_dock_widget, central_dock_area)
59-
self.menuView.addAction(data_dock_widget.toggleViewAction())
60-
6137
table = QTableWidget()
6238
table.setColumnCount(3)
6339
table.setRowCount(10)
64-
table_dock_widget = QtAds.CDockWidget("Table")
40+
table_dock_widget = QtAds.CDockWidget("Table 1")
41+
table_dock_widget.setWidget(table)
42+
table_dock_widget.setMinimumSizeHintMode(QtAds.CDockWidget.MinimumSizeHintFromDockWidget)
43+
table_dock_widget.resize(250, 150)
44+
table_dock_widget.setMinimumSize(200, 150)
45+
table_area = self.dock_manager.addDockWidget(QtAds.DockWidgetArea.LeftDockWidgetArea, table_dock_widget)
46+
self.menuView.addAction(table_dock_widget.toggleViewAction())
47+
48+
table = QTableWidget()
49+
table.setColumnCount(5)
50+
table.setRowCount(1020)
51+
table_dock_widget = QtAds.CDockWidget("Table 2")
6552
table_dock_widget.setWidget(table)
6653
table_dock_widget.setMinimumSizeHintMode(QtAds.CDockWidget.MinimumSizeHintFromDockWidget)
6754
table_dock_widget.resize(250, 150)
6855
table_dock_widget.setMinimumSize(200, 150)
69-
self.dock_manager.addDockWidget(QtAds.DockWidgetArea.BottomDockWidgetArea, table_dock_widget, file_area)
56+
table_area = self.dock_manager.addDockWidget(QtAds.DockWidgetArea.BottomDockWidgetArea, table_dock_widget, table_area)
7057
self.menuView.addAction(table_dock_widget.toggleViewAction())
7158

7259
properties_table = QTableWidget()
@@ -76,15 +63,14 @@ def __init__(self, parent=None):
7663
properties_dock_widget.setWidget(properties_table)
7764
properties_dock_widget.setMinimumSizeHintMode(QtAds.CDockWidget.MinimumSizeHintFromDockWidget)
7865
properties_dock_widget.resize(250, 150)
79-
properties_dock_widget.setMinimumSize(200,150)
66+
properties_dock_widget.setMinimumSize(200, 150)
8067
self.dock_manager.addDockWidget(QtAds.DockWidgetArea.RightDockWidgetArea, properties_dock_widget, central_dock_area)
8168
self.menuView.addAction(properties_dock_widget.toggleViewAction())
8269

8370
self.create_perspective_ui()
8471

8572
def create_perspective_ui(self):
8673
save_perspective_action = QAction("Create Perspective", self)
87-
save_perspective_action.setIcon(svg_icon(":/adsdemo/images/picture_in_picture.svg"))
8874
save_perspective_action.triggered.connect(self.save_perspective)
8975
perspective_list_action = QWidgetAction(self)
9076
self.perspective_combobox = QComboBox(self)

examples/dockindock/dockindock.py

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
import sys
2+
3+
from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, QMessageBox,
4+
QInputDialog, QMenu, QLineEdit)
5+
from PyQt5.QtGui import QIcon
6+
from PyQtAds import QtAds
7+
8+
from dockindockmanager import DockInDockManager
9+
from perspectiveactions import LoadPerspectiveAction, RemovePerspectiveAction
10+
11+
12+
class DockInDockWidget(QWidget):
13+
def __init__(self, parent, perspectives_manager: 'PerspectivesManager', can_create_new_groups: bool = False, top_level_widget = None):
14+
super().__init__(parent)
15+
16+
if top_level_widget is not None:
17+
self.__can_create_new_groups = top_level_widget.can_create_new_groups
18+
else:
19+
self.__can_create_new_groups = can_create_new_groups
20+
self.__top_level_dock_widget = top_level_widget if top_level_widget else self
21+
self.__perspectives_manager = perspectives_manager
22+
self.__new_perspective_default_name: str = ''
23+
24+
layout = QVBoxLayout(self)
25+
layout.setContentsMargins(0,0,0,0)
26+
self.__mgr = DockInDockManager(self)
27+
layout.addWidget(self.__mgr)
28+
29+
def getManager(self) -> 'DockInDockManager':
30+
return self.__mgr
31+
32+
def getTopLevelDockWidget(self) -> 'DockInDockWidget':
33+
return self.__top_level_dock_widget
34+
35+
def canCreateNewGroups(self) -> bool:
36+
return self.__can_create_new_groups
37+
38+
def getPerspectivesManager(self) -> 'PerspectivesManager':
39+
return self.__perspectives_manager
40+
41+
def addTabWidget(self, widget: QWidget, name: str, after: QtAds.CDockAreaWidget, icon = QIcon()) -> QtAds.CDockAreaWidget:
42+
for existing in self.getTopLevelDockWidget().getManager().allDockWidgets(True, True):
43+
if existing[1].objectName() == name:
44+
QMessageBox.critical(self, "Error", "Name '" + name + "' already in use")
45+
return
46+
47+
dock_widget = QtAds.CDockWidget(name)
48+
dock_widget.setWidget(widget)
49+
dock_widget.setIcon(icon)
50+
51+
# Add the dock widget to the top dock widget area
52+
return self.__mgr.addDockWidget(QtAds.CenterDockWidgetArea, dock_widget, after)
53+
54+
def isTopLevel(self) -> bool:
55+
return not self.objectName()
56+
57+
def getGroupNameError(self, group_name: str) -> str:
58+
if not group_name:
59+
return "Group must have a non-empty name"
60+
61+
dock_managers = self.__mgr.allManagers(True, True)
62+
for mgr in dock_managers:
63+
if mgr.getGroupName() == group_name:
64+
return "Group name '" + group_name + "' already used"
65+
66+
return ""
67+
68+
def createGroup(self, group_name: str, insert_pos: QtAds.CDockAreaWidget, icon = QIcon()) -> 'DockInDockWidget':
69+
error = self.getGroupNameError(group_name)
70+
if error:
71+
QMessageBox.critical(None, "Error", error)
72+
return
73+
74+
child = DockInDockWidget(self, self.__top_level_dock_widget, self.__perspectives_manager)
75+
child.setObjectName(group_name)
76+
77+
dock_widget = QtAds.CDockWidget(group_name)
78+
dock_widget.setWidget(child)
79+
dock_widget.setIcon(icon)
80+
81+
insert_pos = self.__mgr.addDockWidget(QtAds.CenterDockWidgetArea, dock_widget, insert_pos)
82+
83+
return child, insert_pos
84+
85+
def destroyGroup(self, widget_to_remove: 'DockInDockWidget') -> None:
86+
top_level_widget = widget_to_remove.getTopLevelDockWidget()
87+
88+
if top_level_widget and top_level_widget != widget_to_remove:
89+
for dock_widget in widget_to_remove.getManager().getWidgetsInGUIOrder(): #don't use allDockWidgets to preserve sub-groups
90+
MoveDockWidgetAction.move(dock_widget, top_level_widget.getManager())
91+
assert not widget_to_remove.getManager().allDockWidgets(True, True)
92+
93+
# find widget's parent:
94+
for dock_widget in top_level_widget.getManager().allDockWidgets(True, True):
95+
if dockwidget[1].widget() == widget_to_remove:
96+
dockwidget[0].removeDockWidget(dockwidget[1])
97+
del dockwidget[1]
98+
# delete widgetToRemove; automatically deleted when dockWidget is deleted
99+
widget_to_remove = None
100+
break
101+
102+
assert widget_to_remove == None
103+
else:
104+
assert False
105+
106+
def attachViewMenu(self, menu: QMenu) -> None:
107+
menu.aboutToShow.connect(self.autoFillAttachedViewMenu)
108+
109+
def autoFillAttachedViewMenu(self) -> None:
110+
menu = self.sender()
111+
112+
if menu:
113+
menu.clear()
114+
self.setupViewMenu(menu)
115+
else:
116+
assert False
117+
118+
def setupViewMenu(self, menu):
119+
dock_managers = self.__mgr.allManagers(True, True)
120+
121+
has_perspectives_menu = False
122+
if self.getTopLevelDockWidget() == self:
123+
has_perspectives_menu = (self.__perspectives_manager != None)
124+
else:
125+
assert False
126+
127+
organize = menu
128+
if has_perspectives_menu:
129+
organize = menu.addMenu("Organize")
130+
131+
self.setupMenu(organize, dock_managers)
132+
133+
if has_perspectives_menu:
134+
perspectives = menu.addMenu("Perspectives")
135+
self.fillPerspectivesMenu(perspectives)
136+
137+
def setupMenu(self, menu: QMenu, move_to: 'list[DockInDockManager]') -> None:
138+
self.__mgr.fillViewMenu(menu, move_to)
139+
menu.addSeparator()
140+
move_menu = menu.addMenu("Move")
141+
self.__mgr.fillMoveMenu(move_menu, move_to)
142+
143+
def fillPerspectivesMenu(self, menu: QMenu):
144+
menu.addAction("Create perspective...", self.createPerspective)
145+
perspectives_names = []
146+
if self.__perspectives_manager:
147+
perspectives_names = self.__perspectives_manager.perspectiveNames()
148+
149+
if perspectives_names:
150+
load = menu.addMenu("Load perspective")
151+
for name in perspectives_names:
152+
load.addAction(LoadPerspectiveAction(load, name, self))
153+
remove = menu.addMenu("Remove perspective")
154+
for name in perspectives_names:
155+
remove.addAction(RemovePerspectiveAction(remove, name, self))
156+
157+
def setNewPerspectiveDefaultName(default_name: str) -> None:
158+
self.__new_perspective_default_name = default_name
159+
160+
def createPerspective(self) -> None:
161+
if not self.__perspectives_manager:
162+
return
163+
164+
name = self.__new_perspective_default_name
165+
if self.__new_perspective_default_name:
166+
index = 2
167+
while name in self.__perspectives_manager.perspectiveNames():
168+
name = f"{self.__new_perspective_default_name}({index})"
169+
index += 1
170+
171+
while True:
172+
name, ok = QInputDialog.getText(None, "Create perspective", "Enter perspective name", QLineEdit.Normal, name)
173+
if ok:
174+
if not name:
175+
QMessageBox.critical(None, "Error", "Perspective name cannot be empty")
176+
continue
177+
elif name in self.__perspectives_manager.perspectiveNames():
178+
if QMessageBox.critical(None, "Error", f"Perspective '{name}' already exists, overwrite it?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) == QMessageBox.No:
179+
continue
180+
181+
self.__perspectives_manager.addPerspective(name, self)
182+
break
183+
else:
184+
break
185+
186+
def dumpStatus(self, echo: callable = print, widget: QtAds.CDockWidget = None, tab: str = '', suffix: str = '') -> str:
187+
if widget is not None:
188+
as_mgr = DockInDockManager.dockInAManager(widget)
189+
if as_mgr:
190+
as_mgr.parent().dumpStatus(tab=tab)
191+
else:
192+
echo(tab + widget.objectName() + suffix)
193+
else:
194+
echo(tab + "Group: " + self.getManager().getGroupName())
195+
tab += " "
196+
visible_widgets = set()
197+
for widget in self.getManager().getWidgetsInGUIOrder():
198+
visible_widgets.add(widget)
199+
self.dumpStatus(widget=widget, tab=tab)
200+
201+
for closed in self.getManager().dockWidgetsMap().values():
202+
if not closed in visible_widgets:
203+
self.dumpStatus(widget=closed, tab=tab, suffix=" (closed)")

0 commit comments

Comments
 (0)