mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2024-12-25 23:51:33 +08:00
8cc9cc25ad
* FIX: Add Q_OS_MACOS flag to moc compiler. * (Python) Demo and example from @n-elie. * FIX: Addressing some sip files that were inconsistent with the header files. * (Python) Addressing comments by @n-elie and switching to use WS_X11 for platform checks. * (Python) Wrap definition of tFloatingWidgetBase to avoid 'Already Defined' error and fix include path for sip/linux/FloatingWidgetTitleBar.sip. * Remove simple.py * Fix case sensitive ui file loading in Linux * Add windows case in get_moc_args * Remove conda recipe Co-authored-by: n-elie <40382614+n-elie@users.noreply.github.com>
506 lines
22 KiB
Python
506 lines
22 KiB
Python
import datetime
|
|
import logging
|
|
import os
|
|
import sys
|
|
|
|
from PyQt5 import uic
|
|
from PyQt5.QtCore import (QCoreApplication, QDir, Qt, QSettings, QSignalBlocker,
|
|
QRect, QPoint, qDebug, qInstallMessageHandler,
|
|
QtDebugMsg, QtInfoMsg, QtWarningMsg,
|
|
QtCriticalMsg, QtFatalMsg)
|
|
from PyQt5.QtGui import (QGuiApplication, QIcon, QCloseEvent)
|
|
from PyQt5.QtWidgets import (QCalendarWidget, QFileSystemModel, QFrame, QLabel,
|
|
QMenu, QTreeView, QAction, QWidgetAction,
|
|
QComboBox, QStyle, QSizePolicy, QInputDialog, QMenu,
|
|
QToolButton, QWidget, QPlainTextEdit,
|
|
QTableWidget, QTableWidgetItem, QApplication,
|
|
QMessageBox)
|
|
try:
|
|
from PyQt5.QAxContainer import QAxWidget
|
|
except ImportError:
|
|
ACTIVEX_AVAILABLE = False
|
|
else:
|
|
ACTIVEX_AVAILABLE = True
|
|
|
|
from PyQtAds import QtAds
|
|
|
|
import rc # pyrcc5 demo.qrc -o rc.py
|
|
|
|
UI_FILE = os.path.join(os.path.dirname(__file__), 'mainwindow.ui')
|
|
MainWindowUI, MainWindowBase = uic.loadUiType(UI_FILE)
|
|
|
|
|
|
class _State:
|
|
label_count = 0
|
|
calendar_count = 0
|
|
file_system_count = 0
|
|
editor_count = 0
|
|
table_count = 0
|
|
activex_count = 0
|
|
|
|
|
|
def features_string(dock_widget: QtAds.CDockWidget) -> str:
|
|
'''Function returns a features string with closable (c), movable (m) and floatable (f)
|
|
features. i.e. The following string is for a not closable but movable and floatable
|
|
widget: c- m+ f+'''
|
|
|
|
f = dock_widget.features()
|
|
closable = f & QtAds.CDockWidget.DockWidgetClosable
|
|
movable = f & QtAds.CDockWidget.DockWidgetMovable
|
|
floatable = f &QtAds.CDockWidget.DockWidgetFloatable
|
|
|
|
return "c{} m{} f{}".format("+" if closable else "-",
|
|
"+" if movable else "-",
|
|
"+" if floatable else "-")
|
|
|
|
|
|
def append_feature_string_to_window_title(dock_widget: QtAds.CDockWidget):
|
|
'''Appends the string returned by features_string() to the window title of
|
|
the given DockWidget'''
|
|
|
|
dock_widget.setWindowTitle(dock_widget.windowTitle() + " ({})".format(features_string(dock_widget)))
|
|
|
|
|
|
def svg_icon(filename: str):
|
|
'''Helper function to create an SVG icon'''
|
|
# This is a workaround, because because in item views SVG icons are not
|
|
# properly scaled an look blurry or pixelate
|
|
icon = QIcon(filename)
|
|
icon.addPixmap(icon.pixmap(92))
|
|
return icon
|
|
|
|
|
|
def create_long_text_label_dock_widget(view_menu: QMenu) -> QtAds.CDockWidget:
|
|
label = QLabel()
|
|
label.setWordWrap(True)
|
|
label.setAlignment(Qt.AlignTop | Qt.AlignLeft)
|
|
label.setText('''\
|
|
Label {} {} - Lorem ipsum dolor sit amet, consectetuer
|
|
adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum
|
|
sociis natoque penatibus et magnis dis parturient montes, nascetur
|
|
ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium
|
|
quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla
|
|
vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut,
|
|
imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis
|
|
pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi.
|
|
Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu,
|
|
consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra
|
|
quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet.
|
|
'''.format(_State.label_count, datetime.datetime.now().strftime("%H:%M:%S:%f")))
|
|
dock_widget = QtAds.CDockWidget("Label {}".format(_State.label_count))
|
|
_State.label_count += 1
|
|
dock_widget.setWidget(label)
|
|
|
|
view_menu.addAction(dock_widget.toggleViewAction())
|
|
return dock_widget
|
|
|
|
|
|
def create_calendar_dock_widget(view_menu: QMenu) -> QtAds.CDockWidget:
|
|
widget = QCalendarWidget()
|
|
|
|
dock_widget = QtAds.CDockWidget("Calendar {}".format(_State.calendar_count))
|
|
_State.calendar_count += 1
|
|
dock_widget.setWidget(widget)
|
|
dock_widget.setToggleViewActionMode(QtAds.CDockWidget.ActionModeShow)
|
|
dock_widget.setIcon(svg_icon(":/adsdemo/images/date_range.svg"))
|
|
view_menu.addAction(dock_widget.toggleViewAction())
|
|
return dock_widget
|
|
|
|
|
|
def create_file_system_tree_dock_widget(view_menu: QMenu) -> QtAds.CDockWidget:
|
|
widget = QTreeView()
|
|
widget.setFrameShape(QFrame.NoFrame)
|
|
|
|
m = QFileSystemModel(widget)
|
|
m.setRootPath(QDir.currentPath())
|
|
widget.setModel(m)
|
|
|
|
dock_widget = QtAds.CDockWidget("Filesystem {}".format(_State.file_system_count))
|
|
_State.file_system_count += 1
|
|
dock_widget.setWidget(widget)
|
|
view_menu.addAction(dock_widget.toggleViewAction())
|
|
return dock_widget
|
|
|
|
|
|
def create_editor_widget(view_menu: QMenu) -> QtAds.CDockWidget:
|
|
widget = QPlainTextEdit()
|
|
widget.setPlaceholderText("This is an editor. If you close the editor, it will be "
|
|
"deleted. Enter your text here.")
|
|
widget.setStyleSheet("border: none")
|
|
dock_widget = QtAds.CDockWidget("Editor {}".format(_State.editor_count))
|
|
_State.editor_count += 1
|
|
dock_widget.setWidget(widget)
|
|
dock_widget.setIcon(svg_icon(":/adsdemo/images/edit.svg"))
|
|
dock_widget.setFeature(QtAds.CDockWidget.CustomCloseHandling, True)
|
|
view_menu.addAction(dock_widget.toggleViewAction())
|
|
|
|
options_menu = QMenu(dock_widget)
|
|
options_menu.setTitle("Options")
|
|
options_menu.setToolTip(options_menu.title())
|
|
options_menu.setIcon(svg_icon(":/adsdemo/images/custom-menu-button.svg"))
|
|
menu_action = options_menu.menuAction()
|
|
# The object name of the action will be set for the QToolButton that
|
|
# is created in the dock area title bar. You can use this name for CSS
|
|
# styling
|
|
menu_action.setObjectName("options_menu")
|
|
dock_widget.setTitleBarActions([options_menu.menuAction()])
|
|
a = options_menu.addAction("Clear Editor")
|
|
a.triggered.connect(widget.clear)
|
|
|
|
return dock_widget
|
|
|
|
|
|
def create_table_widget(view_menu: QMenu) -> QtAds.CDockWidget:
|
|
widget = QTableWidget()
|
|
dock_widget = QtAds.CDockWidget("Table {}".format(_State.table_count))
|
|
_State.table_count += 1
|
|
COLCOUNT = 5
|
|
ROWCOUNT = 30
|
|
widget.setColumnCount(COLCOUNT)
|
|
widget.setRowCount(ROWCOUNT)
|
|
for col in range(ROWCOUNT):
|
|
widget.setHorizontalHeaderItem(col, QTableWidgetItem("Col {}".format(col+1)))
|
|
for row in range(ROWCOUNT):
|
|
widget.setItem(row, col, QTableWidgetItem("T {:}-{:}".format(row+1, col+1)))
|
|
|
|
dock_widget.setWidget(widget)
|
|
dock_widget.setIcon(svg_icon(":/adsdemo/images/grid_on.svg"))
|
|
view_menu.addAction(dock_widget.toggleViewAction())
|
|
return dock_widget
|
|
|
|
|
|
if ACTIVEX_AVAILABLE:
|
|
def create_activex_widget(view_menu: QMenu, parent: QWidget = None) -> QtAds.CDockWidget:
|
|
widget = QAxWidget("{6bf52a52-394a-11d3-b153-00c04f79faa6}", parent)
|
|
dock_widget = QtAds.CDockWidget("Active X {}".format(_State.activex_count))
|
|
_State.activex_count += 1
|
|
dock_widget.setWidget(widget)
|
|
view_menu.addAction(dock_widget.toggleViewAction())
|
|
return dock_widget
|
|
|
|
|
|
class CustomComponentsFactory(QtAds.CDockComponentsFactory):
|
|
|
|
def createDockAreaTitleBar(self, dock_area: QtAds.CDockAreaWidget) -> QtAds.CDockAreaTitleBar:
|
|
title_bar = QtAds.CDockAreaTitleBar(dock_area)
|
|
custom_button = QToolButton(dock_area)
|
|
custom_button.setToolTip("Help")
|
|
custom_button.setIcon(svg_icon(":/adsdemo/images/help_outline.svg"))
|
|
custom_button.setAutoRaise(True)
|
|
index = title_bar.indexOf(title_bar.button(QtAds.TitleBarButtonTabsMenu))
|
|
title_bar.insertWidget(index + 1, custom_button)
|
|
return title_bar
|
|
|
|
|
|
|
|
class MainWindow(MainWindowUI, MainWindowBase):
|
|
save_perspective_action: QAction
|
|
perspective_list_action: QWidgetAction
|
|
perspective_combo_box: QComboBox
|
|
dock_manager: QtAds.CDockManager
|
|
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
self.save_perspective_action = None
|
|
self.perspective_list_action = None
|
|
self.perspective_combo_box = None
|
|
self.dock_manager = None
|
|
|
|
self.setupUi(self)
|
|
self.create_actions()
|
|
|
|
# uncomment the following line if the tab close button should be
|
|
# a QToolButton instead of a QPushButton
|
|
# QtAds.CDockManager.setConfigFlags(QtAds.CDockManager.configFlags() | QtAds.CDockManager.TabCloseButtonIsToolButton)
|
|
|
|
# uncomment the following line if you want a fixed tab width that does
|
|
# not change if the visibility of the close button changes
|
|
# QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.RetainTabSizeWhenCloseButtonHidden, True)
|
|
|
|
# uncomment the follwing line if you want to use non opaque undocking and splitter
|
|
# movements
|
|
# QtAds.CDockManager.setConfigFlags(QtAds.CDockManager.DefaultNonOpaqueConfig)
|
|
|
|
# Now create the dock manager and its content
|
|
self.dock_manager = QtAds.CDockManager(self)
|
|
|
|
# Uncomment the following line to have the old style where the dock
|
|
# area close button closes the active tab
|
|
# QtAds.CDockManager.setConfigFlags(QtAds.CDockManager.DockAreaHasCloseButton
|
|
# | QtAds.CDockManager.DockAreaCloseButtonClosesTab)
|
|
self.perspective_combo_box.activated[str].connect(self.dock_manager.openPerspective)
|
|
|
|
self.create_content()
|
|
# Default window geometry - center on screen
|
|
self.resize(1280, 720)
|
|
self.setGeometry(QStyle.alignedRect(
|
|
Qt.LeftToRight, Qt.AlignCenter, self.frameSize(),
|
|
QGuiApplication.primaryScreen().availableGeometry()))
|
|
|
|
# self.restore_state()
|
|
self.restore_perspectives()
|
|
|
|
def create_content(self):
|
|
# Test container docking
|
|
view_menu = self.menuView
|
|
dock_widget = create_calendar_dock_widget(view_menu)
|
|
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetClosable, False)
|
|
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetMovable, False)
|
|
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetFloatable, False)
|
|
special_dock_area = self.dock_manager.addDockWidget(QtAds.LeftDockWidgetArea, dock_widget)
|
|
|
|
# For this Special Dock Area we want to avoid dropping on the center of it (i.e. we don't want this widget to be ever tabbified):
|
|
special_dock_area.setAllowedAreas(QtAds.OuterDockAreas)
|
|
# special_dock_area.setAllowedAreas(QtAds.LeftDockWidgetArea | QtAds.RightDockWidgetArea) # just for testing
|
|
|
|
self.dock_manager.addDockWidget(QtAds.LeftDockWidgetArea, create_long_text_label_dock_widget(view_menu))
|
|
file_system_widget = create_file_system_tree_dock_widget(view_menu)
|
|
tool_bar = file_system_widget.createDefaultToolBar()
|
|
tool_bar.addAction(self.actionSaveState)
|
|
tool_bar.addAction(self.actionRestoreState)
|
|
file_system_widget.setFeature(QtAds.CDockWidget.DockWidgetFloatable, False)
|
|
append_feature_string_to_window_title(file_system_widget)
|
|
self.dock_manager.addDockWidget(QtAds.BottomDockWidgetArea, file_system_widget)
|
|
|
|
file_system_widget = create_file_system_tree_dock_widget(view_menu)
|
|
tool_bar = file_system_widget.createDefaultToolBar()
|
|
tool_bar.addAction(self.actionSaveState)
|
|
tool_bar.addAction(self.actionRestoreState)
|
|
file_system_widget.setFeature(QtAds.CDockWidget.DockWidgetMovable, False)
|
|
file_system_widget.setFeature(QtAds.CDockWidget.DockWidgetFloatable, False)
|
|
append_feature_string_to_window_title(file_system_widget)
|
|
|
|
# Test custom factory - we inject a help button into the title bar
|
|
self.factory = CustomComponentsFactory()
|
|
QtAds.CDockComponentsFactory.setFactory(self.factory)
|
|
top_dock_area = self.dock_manager.addDockWidget(QtAds.TopDockWidgetArea, file_system_widget)
|
|
QtAds.CDockComponentsFactory.resetDefaultFactory()
|
|
|
|
|
|
# We create a calendar widget and clear all flags to prevent the dock area
|
|
# from closing
|
|
dock_widget = create_calendar_dock_widget(view_menu)
|
|
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetClosable, False)
|
|
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetMovable, False)
|
|
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetFloatable, False)
|
|
dock_widget.setTabToolTip("Tab ToolTip\nHodie est dies magna")
|
|
dock_area = self.dock_manager.addDockWidget(QtAds.CenterDockWidgetArea, dock_widget, top_dock_area)
|
|
|
|
# Now we add a custom button to the dock area title bar that will create
|
|
# new editor widgets when clicked
|
|
custom_button = QToolButton(dock_area)
|
|
custom_button.setToolTip("Create Editor")
|
|
custom_button.setIcon(svg_icon(":/adsdemo/images/plus.svg"))
|
|
custom_button.setAutoRaise(True)
|
|
title_bar = dock_area.titleBar()
|
|
index = title_bar.indexOf(title_bar.tabBar())
|
|
title_bar.insertWidget(index + 1, custom_button)
|
|
def on_button_clicked():
|
|
dock_widget = create_editor_widget(self.menuView)
|
|
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetDeleteOnClose, True)
|
|
self.dock_manager.addDockWidgetTabToArea(dock_widget, dock_area)
|
|
dock_widget.closeRequested.connect(self.on_editor_close_requested)
|
|
custom_button.clicked.connect(on_button_clicked)
|
|
|
|
# Test dock area docking
|
|
right_dock_area = self.dock_manager.addDockWidget(
|
|
QtAds.RightDockWidgetArea,
|
|
create_long_text_label_dock_widget(view_menu), top_dock_area)
|
|
self.dock_manager.addDockWidget(
|
|
QtAds.TopDockWidgetArea,
|
|
create_long_text_label_dock_widget(view_menu), right_dock_area)
|
|
|
|
bottom_dock_area = self.dock_manager.addDockWidget(
|
|
QtAds.BottomDockWidgetArea,
|
|
create_long_text_label_dock_widget(view_menu), right_dock_area)
|
|
|
|
self.dock_manager.addDockWidget(
|
|
QtAds.CenterDockWidgetArea,
|
|
create_long_text_label_dock_widget(view_menu), right_dock_area)
|
|
self.dock_manager.addDockWidget(
|
|
QtAds.CenterDockWidgetArea,
|
|
create_long_text_label_dock_widget(view_menu), bottom_dock_area)
|
|
|
|
action = self.menuView.addAction("Set {} floating".format(dock_widget.windowTitle()))
|
|
action.triggered.connect(dock_widget.setFloating)
|
|
|
|
if ACTIVEX_AVAILABLE:
|
|
flags = self.dock_manager.configFlags()
|
|
if flags & QtAds.CDockManager.OpaqueUndocking:
|
|
self.dock_manager.addDockWidget(QtAds.CenterDockWidgetArea,
|
|
create_activex_widget(view_menu), right_dock_area)
|
|
|
|
for dock_widget in self.dock_manager.dockWidgetsMap().values():
|
|
dock_widget.viewToggled.connect(self.on_view_toggled)
|
|
dock_widget.visibilityChanged.connect(self.on_view_visibility_changed)
|
|
|
|
def create_actions(self):
|
|
self.toolBar.addAction(self.actionSaveState)
|
|
self.toolBar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
|
|
self.actionSaveState.setIcon(svg_icon(":/adsdemo/images/save.svg"))
|
|
self.toolBar.addAction(self.actionRestoreState)
|
|
self.actionRestoreState.setIcon(svg_icon(":/adsdemo/images/restore.svg"))
|
|
|
|
self.save_perspective_action = QAction("Create Perspective", self)
|
|
self.save_perspective_action.setIcon(svg_icon(":/adsdemo/images/picture_in_picture.svg"))
|
|
self.save_perspective_action.triggered.connect(self.save_perspective)
|
|
self.perspective_list_action = QWidgetAction(self)
|
|
self.perspective_combo_box = QComboBox(self)
|
|
self.perspective_combo_box.setSizeAdjustPolicy(QComboBox.AdjustToContents)
|
|
self.perspective_combo_box.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
|
|
self.perspective_list_action.setDefaultWidget(self.perspective_combo_box)
|
|
self.toolBar.addSeparator()
|
|
self.toolBar.addAction(self.perspective_list_action)
|
|
self.toolBar.addAction(self.save_perspective_action)
|
|
|
|
a = self.toolBar.addAction("Create Editor")
|
|
a.setToolTip("Creates floating dynamic dockable editor windows that are deleted on close")
|
|
a.setIcon(svg_icon(":/adsdemo/images/note_add.svg"))
|
|
a.triggered.connect(self.create_editor)
|
|
|
|
a = self.toolBar.addAction("Create Table")
|
|
a.setToolTip("Creates floating dynamic dockable table with millions of entries")
|
|
a.setIcon(svg_icon(":/adsdemo/images/grid_on.svg"))
|
|
a.triggered.connect(self.create_table)
|
|
|
|
def closeEvent(self, event: QCloseEvent):
|
|
self.save_state()
|
|
super().closeEvent(event)
|
|
|
|
def on_action_save_state_triggered(state: bool):
|
|
qDebug("MainWindow::on_action_save_state_triggered")
|
|
self.save_state()
|
|
|
|
def on_action_restore_state_triggered(state: bool):
|
|
qDebug("MainWindow::on_action_restore_state_triggered")
|
|
self.restore_state()
|
|
|
|
def save_perspective(self):
|
|
perspective_name, ok = QInputDialog.getText(self, "Save perspective",
|
|
"Enter unique name:")
|
|
|
|
if ok and perspective_name:
|
|
self.dock_manager.addPerspective(perspective_name)
|
|
_ = QSignalBlocker(self.perspective_combo_box)
|
|
self.perspective_combo_box.clear()
|
|
self.perspective_combo_box.addItems(self.dock_manager.perspectiveNames())
|
|
self.perspective_combo_box.setCurrentText(perspective_name)
|
|
|
|
self.save_perspectives()
|
|
|
|
def on_view_toggled(self, open: bool):
|
|
dock_widget = self.sender()
|
|
if dock_widget is None:
|
|
return
|
|
|
|
qDebug("{} view_toggled({})".format(dock_widget.objectName(), open))
|
|
|
|
def on_view_visibility_changed(self, visible: bool):
|
|
dock_widget = self.sender()
|
|
if dock_widget is None:
|
|
return
|
|
|
|
qDebug("{} visibility_changed({})".format(dock_widget.objectName(), visible))
|
|
|
|
def create_editor(self):
|
|
dock_widget = create_editor_widget(self.menuView)
|
|
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetDeleteOnClose, True)
|
|
floating_widget = self.dock_manager.addDockWidgetFloating(dock_widget)
|
|
floating_widget.move(QPoint(20, 20))
|
|
dock_widget.closeRequested.connect(self.on_editor_close_requested)
|
|
|
|
def on_editor_close_requested(self):
|
|
dock_widget = self.sender()
|
|
result = QMessageBox.question(self, "Close Editor",
|
|
"Editor {} contains unsaved changes? Would you like to close it?".format(dock_widget.windowTitle()))
|
|
if result == QMessageBox.Yes:
|
|
dock_widget.closeDockWidget()
|
|
|
|
def create_table(self):
|
|
dock_widget = create_table_widget(self.menuView)
|
|
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetDeleteOnClose, True)
|
|
floating_widget = self.dock_manager.addDockWidgetFloating(dock_widget)
|
|
floating_widget.move(QPoint(40, 40))
|
|
|
|
def save_state(self):
|
|
'''
|
|
Saves the dock manager state and the main window geometry
|
|
'''
|
|
settings = QSettings("Settings.ini", QSettings.IniFormat)
|
|
settings.setValue("mainWindow/Geometry", self.saveGeometry())
|
|
settings.setValue("mainWindow/State", self.saveState())
|
|
settings.setValue("mainWindow/DockingState", self.dock_manager.saveState())
|
|
|
|
def restore_state(self):
|
|
'''
|
|
Restores the dock manager state
|
|
'''
|
|
settings = QSettings("Settings.ini", QSettings.IniFormat)
|
|
geom = settings.value("mainWindow/Geometry")
|
|
if geom is not None:
|
|
self.restoreGeometry(geom)
|
|
|
|
state = settings.value("mainWindow/State")
|
|
if state is not None:
|
|
self.restoreState(state)
|
|
|
|
state = settings.value("mainWindow/DockingState")
|
|
if state is not None:
|
|
self.dock_manager.restore_state(state)
|
|
|
|
def save_perspectives(self):
|
|
'''
|
|
Save the list of perspectives
|
|
'''
|
|
settings = QSettings("Settings.ini", QSettings.IniFormat)
|
|
self.dock_manager.savePerspectives(settings)
|
|
|
|
def restore_perspectives(self):
|
|
'''
|
|
Restore the perspective listo of the dock manager
|
|
'''
|
|
settings = QSettings("Settings.ini", QSettings.IniFormat)
|
|
self.dock_manager.loadPerspectives(settings)
|
|
self.perspective_combo_box.clear()
|
|
self.perspective_combo_box.addItems(self.dock_manager.perspectiveNames())
|
|
|
|
def save_perspective(self):
|
|
perspective_name, ok = QInputDialog.getText(self, 'Save perspective', 'Enter unique name:')
|
|
if ok and perspective_name:
|
|
self.dock_manager.addPerspective(perspective_name)
|
|
_ = QSignalBlocker(self.perspective_combo_box)
|
|
self.perspective_combo_box.clear()
|
|
self.perspective_combo_box.addItems(self.dock_manager.perspectiveNames())
|
|
self.perspective_combo_box.setCurrentText(perspective_name)
|
|
self.save_perspectives()
|
|
|
|
|
|
def my_message_output(type, context, msg):
|
|
if type == QtDebugMsg:
|
|
print("Debug: {} ({}:{}, {})".format(msg, context.file, context.line, context.function))
|
|
elif type == QtInfoMsg:
|
|
print("Info: {} ({}:{}, {})".format(msg, context.file, context.line, context.function))
|
|
elif type == QtWarningMsg:
|
|
print("Warning: {} ({}:{}, {})".format(msg, context.file, context.line, context.function))
|
|
elif type == QtCriticalMsg:
|
|
print("Critical: {} ({}:{}, {})".format(msg, context.file, context.line, context.function))
|
|
elif type == QtFatalMsg:
|
|
print("Fatal: {} ({}:{}, {})".format(msg, context.file, context.line, context.function))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
|
|
QGuiApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
|
|
app = QApplication(sys.argv)
|
|
app.setQuitOnLastWindowClosed(True)
|
|
|
|
with open(os.path.join(os.path.dirname(__file__), "app.css"), "r") as style_sheet_file:
|
|
app.setStyleSheet(style_sheet_file.read())
|
|
|
|
qInstallMessageHandler(my_message_output)
|
|
qDebug("Message handler test")
|
|
|
|
mw = MainWindow()
|
|
mw.show()
|
|
app.exec_()
|