def onEdit(self): editCmd = ConfigManager().getPrefsValue("PREFS", "General/EditorCmd") tempFilesDir = self.canvasRef().getApp().getTempDirectory() if self._filePath == "": # if no file assotiated - create one uidStr = str(self.uid).replace("-", "") self._filePath = os.path.join(tempFilesDir, "{}.py".format(uidStr)) if not os.path.exists(self._filePath): f = open(self._filePath, 'w') if self.nodeData == "": f.write(INITIAL_CODE) else: f.write(self.nodeData) f.close() filePathString = '"{}"'.format(self._filePath) editCmd = editCmd.replace("@FILE", filePathString) # create file watcher if UIPythonNode.watcher is None: UIPythonNode.watcher = QtCore.QFileSystemWatcher() if self._filePath not in UIPythonNode.watcher.files(): UIPythonNode.watcher.addPath(self._filePath) try: UIPythonNode.watcher.fileChanged.disconnect(self.onFileChanged) except: pass result = UIPythonNode.watcher.fileChanged.connect(self.onFileChanged) self.currentEditorProcess = subprocess.Popen(editCmd) self.fileHandle = open(self._filePath, 'r')
def anchorClickedMethod(self, url): if os.path.exists(url.url().split("::")[0]): editCmd = ConfigManager().getPrefsValue("PREFS", "General/EditorCmd") editCmd = editCmd.replace("@FILE", url.url().replace("::", ":")) subprocess.Popen(editCmd) else: man = self.pyFlowInstance.graphManager node = man.get().findNode(str(url.url())) if node: self.pyFlowInstance.getCanvas().clearSelection() node.getWrapper().setSelected(True) self.pyFlowInstance.getCanvas().frameSelectedNodes()
def savePreferences(self): settings = ConfigManager().getSettings("PREFS") for name, indexWidget in self._indexes.items(): index, widget = indexWidget settings.beginGroup(name) widget.serialize(settings) settings.endGroup() settings.sync()
def __init__(self): self.TextColor = QtGui.QColor(228, 228, 228) self.MainColor = QtGui.QColor(215, 128, 26) self.BgColor = QtGui.QColor(53, 53, 53) self.BgColorDarker = QtGui.QColor(50, 50, 50) self.BgColorBright = QtGui.QColor(82, 82, 82) self.BorderColor = QtGui.QColor(10, 10, 10) self.InputFieldColor = QtGui.QColor(32, 32, 32) self.TextSelectedColor = QtGui.QColor(255, 255, 255) self.ButtonsColor = QtGui.QColor(60, 60, 60) self.CanvasBgColor = QtGui.QColor(35, 35, 35) self.CanvasGridColor = QtGui.QColor(20, 20, 20, 100) self.CanvasGridColorDarker = QtGui.QColor(20, 20, 20) self.GridSizeFine = [10] self.GridSizeHuge = [100] self.DrawNumbers = [0] self.storeDeffaults() self.presests = {} self.loadPresests(THEMES_PATH) settings = QtCore.QSettings(ConfigManager().PREFERENCES_CONFIG_PATH, QtCore.QSettings.IniFormat) settings.beginGroup("Preferences") settings.beginGroup("Theme") try: if settings.value('Theme_Name'): self.loadFromData(self.presests[settings.value('Theme_Name')]) except: pass
def onEdit(self): settings = QtCore.QSettings(ConfigManager().PREFERENCES_CONFIG_PATH, QtCore.QSettings.IniFormat) editCmd = settings.value("Preferences/General/EditorCmd") tempFilesDir = self.canvasRef().getApp().getTempDirectory() if self._filePath == "": # if no file assotiated - create one self._filePath = os.path.join(tempFilesDir, "{}.py".format(str(self.uid))) if not os.path.exists(self._filePath): f = open(self._filePath, 'w') if self.nodeData == "": f.write(INITIAL_CODE) else: f.write(self.nodeData) f.close() filePathString = '"{}"'.format(self._filePath) editCmd = editCmd.replace("@FILE", filePathString) # create file watcher if self._filePath not in self.watcher.files(): UIPythonNode.watcher.addPath(self._filePath) try: UIPythonNode.watcher.fileChanged.disconnect(self.onFileChanged) except: pass result = UIPythonNode.watcher.fileChanged.connect(self.onFileChanged) self.currentEditorProcess = subprocess.Popen(editCmd) self.fileHandle = open(self._filePath, 'r')
def tryCreateDefaults(self): settings = ConfigManager().getSettings("PREFS") groups = settings.childGroups() for name, indexWidget in self._indexes.items(): index, widget = indexWidget bInitDefaults = False if name not in groups: bInitDefaults = True settings.beginGroup(name) if bInitDefaults: widget.initDefaults(settings) settings.endGroup() settings.sync()
def showEvent(self, event): settings = ConfigManager().getSettings("PREFS") groups = settings.childGroups() for name, indexWidget in self._indexes.items(): index, widget = indexWidget settings.beginGroup(name) widget.onShow(settings) settings.endGroup()
def savePreferences(self): settings = QtCore.QSettings(ConfigManager().PREFERENCES_CONFIG_PATH, QtCore.QSettings.IniFormat, self) settings.beginGroup("Preferences") for name, indexWidget in self._indexes.items(): index, widget = indexWidget settings.beginGroup(name) widget.serialize(settings) settings.endGroup() settings.endGroup() settings.sync()
def showEvent(self, event): settings = QtCore.QSettings(ConfigManager().PREFERENCES_CONFIG_PATH, QtCore.QSettings.IniFormat, self) settings.beginGroup("Preferences") groups = settings.childGroups() for name, indexWidget in self._indexes.items(): index, widget = indexWidget settings.beginGroup(name) widget.onShow(settings) settings.endGroup() settings.endGroup()
def __init__(self, appInstance=None): self.appInstance = appInstance self.TextColor = QtGui.QColor(228, 228, 228) self.MainColor = QtGui.QColor(215, 128, 26) self.BgColor = QtGui.QColor(53, 53, 53) self.BgColorDarker = QtGui.QColor(50, 50, 50) self.BgColorBright = QtGui.QColor(82, 82, 82) self.BorderColor = QtGui.QColor(10, 10, 10) self.LoggerBgColor = QtGui.QColor(35, 35, 35) self.InputFieldColor = QtGui.QColor(32, 32, 32) self.TextSelectedColor = QtGui.QColor(255, 255, 255) self.ButtonsColor = QtGui.QColor(60, 60, 60) self.CanvasBgColor = QtGui.QColor(35, 35, 35) self.CanvasGridColor = QtGui.QColor(20, 20, 20, 100) self.CanvasGridColorDarker = QtGui.QColor(20, 20, 20) self.DrawGrid = [1] self.GridSizeFine = [10] self.GridSizeHuge = [100] self.DrawNumbers = [0] self.SetAppStyleSheet = [1] self.LOD_Number = [4] self.NodeSwitch = [3] self.ConnectionSwitch = [3] self.PinSwitch = [3] self.CanvasSwitch = [3] self.ConnectionMode = [ConnectionTypes.Circuit] self.ConnectionRoundness = [5] self.ConnectionOffset = [20] self.storeDeffaults() self.presets = {} self.loadPresets(THEMES_PATH) try: themeName = ConfigManager().getPrefsValue("PREFS", "Theme/Theme_Name") if themeName: self.loadFromData(self.presets[themeName]) else: if len(self.presets) > 0: self.loadFromData(self.presets[list( self.presets.keys())[0]]) except: pass
def __init__(self, app): self.statePushed = Signal(object) self.stateRemoved = Signal(object) self.stateSelected = Signal(object) self.app = app self.stack = list() try: self._capacity = int(ConfigManager().getPrefsValue("PREFS", "General/HistoryDepth")) except: self._capacity = 10 self.activeState = None
def tryCreateDefaults(self): settings = QtCore.QSettings(ConfigManager().PREFERENCES_CONFIG_PATH, QtCore.QSettings.IniFormat, self) settings.beginGroup("Preferences") groups = settings.childGroups() for name, indexWidget in self._indexes.items(): index, widget = indexWidget bInitDefaults = False if name not in groups: bInitDefaults = True settings.beginGroup(name) if bInitDefaults: widget.initDefaults(settings) settings.endGroup() settings.endGroup() settings.sync()
def getTempDirectory(self): """Returns unique temp directory for application instance. This folder and all it's content will be removed from disc on application shutdown. """ if self.currentTempDir == "": # create app folder in documents # random string used for cases when multiple instances of app are running in the same time tempDirPath = ConfigManager().getPrefsValue("PREFS", "General/TempFilesDir") if tempDirPath[-1:] in ('/', '\\'): tempDirPath = tempDirPath[:-1] self.currentTempDir = "{0}_{1}".format(tempDirPath, generateRandomString()) if not os.path.exists(self.currentTempDir): os.makedirs(self.currentTempDir) return self.currentTempDir
def compute(self, *args, **kwargs): redirectionEnabled = ConfigManager().shouldRedirectOutput() if self.getWrapper() is not None and redirectionEnabled: data = str(self.entity.getData()) if self.entity.dataType != "StringPin": data = data.encode('unicode-escape') if IS_PYTHON2: data = data.replace("\\n", "<br/>") else: if isinstance(data, bytes): data = data.decode("utf-8") data = str(data).replace("\\n", "<br/>") errorLink = """<a href=%s><span style=" text-decoration: underline; color:green;">%s</span></a></p>""" % (self.name, "<br/>%s" % data) logging.getLogger(None).consoleoutput(errorLink) else: print(self.entity.getData()) self.outExec.call()
def closeEvent(self, event): self.tick_timer.stop() self.tick_timer.timeout.disconnect() self.canvasWidget.shoutDown() # save editor config settings = QtCore.QSettings(ConfigManager().APP_SETTINGS_PATH, QtCore.QSettings.IniFormat, self) # clear file each time to capture opened dock tools settings.clear() settings.sync() settings.beginGroup('Editor') settings.setValue("geometry", self.saveGeometry()) settings.setValue("state", self.saveState()) settings.endGroup() # save tools state settings.beginGroup('Tools') for tool in self._tools: if isinstance(tool, ShelfTool): settings.beginGroup("ShelfTools") settings.beginGroup(tool.name()) tool.saveState(settings) settings.endGroup() settings.endGroup() if isinstance(tool, DockTool): settings.beginGroup("DockTools") settings.beginGroup(tool.uniqueName()) tool.saveState(settings) settings.endGroup() settings.endGroup() tool.onDestroy() settings.endGroup() settings.sync() # remove temp directory shutil.rmtree(self.currentTempDir, ignore_errors=True) QMainWindow.closeEvent(self, event)
def __init__(self): self.TextColor = QtGui.QColor(228, 228, 228) self.MainColor = QtGui.QColor(215, 128, 26) self.BgColor = QtGui.QColor(53, 53, 53) self.BgColorDarker = QtGui.QColor(50, 50, 50) self.BgColorBright = QtGui.QColor(82, 82, 82) self.BorderColor = QtGui.QColor(10, 10, 10) self.LoggerBgColor = QtGui.QColor(35, 35, 35) self.InputFieldColor = QtGui.QColor(32, 32, 32) self.TextSelectedColor = QtGui.QColor(255, 255, 255) self.ButtonsColor = QtGui.QColor(60, 60, 60) self.CanvasBgColor = QtGui.QColor(35, 35, 35) self.CanvasGridColor = QtGui.QColor(20, 20, 20, 100) self.CanvasGridColorDarker = QtGui.QColor(20, 20, 20) self.GridSizeFine = [10] self.GridSizeHuge = [100] self.DrawNumbers = [0] self.SetAppStyleSheet = [1] self.storeDeffaults() self.presests = {} self.loadPresests(THEMES_PATH) try: themeName = ConfigManager().getPrefsValue("PREFS", "Theme/Theme_Name") if themeName: self.loadFromData(self.presests[themeName]) except: pass
def instance(parent=None): if PyFlow.appInstance is not None: return PyFlow.appInstance settings = ConfigManager().getSettings("APP_STATE") instance = PyFlow(parent) REGISTER_TOOL("PyFlowBase", LoggerTool) a = GET_TOOLS()["PyFlowBase"][0]() a.setAppInstance(instance) instance.registerToolInstance(a) instance.addDockWidget(a.defaultDockArea(), a) a.setAppInstance(instance) a.onShow() try: extraPackagePaths = [] extraPathsString = ConfigManager().getPrefsValue( "PREFS", "General/ExtraPackageDirs") if extraPathsString is not None: extraPathsString = extraPathsString.rstrip(";") extraPathsRaw = extraPathsString.split(";") for rawPath in extraPathsRaw: if os.path.exists(rawPath): extraPackagePaths.append(os.path.normpath(rawPath)) INITIALIZE(additionalPackageLocations=extraPackagePaths) except Exception as e: QMessageBox.critical(None, "Fatal error", str(e)) return instance.startMainLoop() # populate tools canvas = instance.getCanvas() toolbar = instance.getToolbar() geo = settings.value('Editor/geometry') if geo is not None: instance.restoreGeometry(geo) state = settings.value('Editor/state') if state is not None: instance.restoreState(state) settings.beginGroup("Tools") for packageName, registeredToolSet in GET_TOOLS().items(): for ToolClass in registeredToolSet: if issubclass(ToolClass, ShelfTool): ToolInstance = ToolClass() # prevent to be garbage collected instance.registerToolInstance(ToolInstance) ToolInstance.setAppInstance(instance) action = QAction(instance) action.setIcon(ToolInstance.getIcon()) action.setText(ToolInstance.name()) action.setToolTip(ToolInstance.toolTip()) action.setObjectName(ToolInstance.name()) action.triggered.connect(ToolInstance.do) # check if context menu data available menuBuilder = ToolInstance.contextMenuBuilder() if menuBuilder: menuGenerator = ContextMenuGenerator(menuBuilder) menu = menuGenerator.generate() action.setMenu(menu) toolbar.addAction(action) # step to ShelfTools/ToolName group and pass settings inside settings.beginGroup("ShelfTools") settings.beginGroup(ToolClass.name()) ToolInstance.restoreState(settings) settings.endGroup() settings.endGroup() if issubclass(ToolClass, DockTool): menus = instance.menuBar.findChildren(QMenu) pluginsMenuAction = [ m for m in menus if m.title() == "Plugins" ][0].menuAction() toolsMenu = getOrCreateMenu(instance.menuBar, "Tools") instance.menuBar.insertMenu(pluginsMenuAction, toolsMenu) packageSubMenu = getOrCreateMenu(toolsMenu, packageName) toolsMenu.addMenu(packageSubMenu) showToolAction = packageSubMenu.addAction(ToolClass.name()) icon = ToolClass.getIcon() if icon: showToolAction.setIcon(icon) showToolAction.triggered.connect( lambda pkgName=packageName, toolName=ToolClass.name( ): instance.invokeDockToolByName(pkgName, toolName)) settings.beginGroup("DockTools") childGroups = settings.childGroups() for dockToolGroupName in childGroups: # This dock tool data been saved on last shutdown settings.beginGroup(dockToolGroupName) if dockToolGroupName in [ t.uniqueName() for t in instance._tools ]: continue toolName = dockToolGroupName.split("::")[0] instance.invokeDockToolByName(packageName, toolName, settings) settings.endGroup() settings.endGroup() PyFlow.appInstance = instance EditorHistory().saveState("New file") for name, package in GET_PACKAGES().items(): prefsWidgets = package.PrefsWidgets() if prefsWidgets is not None: for categoryName, widgetClass in prefsWidgets.items(): PreferencesWindow().addCategory(categoryName, widgetClass()) PreferencesWindow().selectByName("General") return instance
def serialize(self, settings): data = InputManager().serialize() with open(ConfigManager().INPUT_CONFIG_PATH, "w") as f: json.dump(data, f, indent=4)
def closeEvent(self, event): self.tick_timer.stop() self.tick_timer.timeout.disconnect() self.canvasWidget.shoutDown() # save editor config settings = ConfigManager().getSettings("APP_STATE") # clear file each time to capture opened dock tools settings.clear() settings.sync() settings.beginGroup('Editor') settings.setValue("geometry", self.saveGeometry()) settings.setValue("state", self.saveState()) settings.endGroup() # save tools state settings.beginGroup('Tools') for tool in self._tools: if isinstance(tool, ShelfTool): settings.beginGroup("ShelfTools") settings.beginGroup(tool.name()) tool.saveState(settings) settings.endGroup() settings.endGroup() if isinstance(tool, DockTool): settings.beginGroup("DockTools") settings.beginGroup(tool.uniqueName()) tool.saveState(settings) settings.endGroup() settings.endGroup() tool.onDestroy() settings.endGroup() settings.sync() # remove temp directory if exists if os.path.exists(self.currentTempDir): shutil.rmtree(self.currentTempDir) QMainWindow.closeEvent(self, event)
from Qt import QtCore from Qt import QtGui from Qt.QtWidgets import QAction, QTextBrowser from PyFlow.UI.Tool.Tool import DockTool from PyFlow.UI.Views.NodeBox import NodesBox from PyFlow.UI.Utils.stylesheet import editableStyleSheet from PyFlow.Core.GraphManager import GraphManagerSingleton from PyFlow.Core.Common import SingletonDecorator from PyFlow.ConfigManager import ConfigManager import sys import logging import json import os import subprocess REDIRECT = ConfigManager().shouldRedirectOutput() logger = logging.getLogger(None) def addLoggingLevel(levelName, levelNum, methodName=None): """ Comprehensively adds a new logging level to the `logging` module and the currently configured logging class. `levelName` becomes an attribute of the `logging` module with the value `levelNum`. `methodName` becomes a convenience method for both `logging` itself and the class returned by `logging.getLoggerClass()` (usually just `logging.Logger`). If `methodName` is not specified, `levelName.lower()` is used.
def closeEvent(self, event): shouldSave = self.shouldSave() if shouldSave == QMessageBox.Yes: if not self.save(): event.ignore() return elif shouldSave == QMessageBox.Discard: event.ignore() return self.tick_timer.stop() self.tick_timer.timeout.disconnect() EditorHistory().shutdown() self.canvasWidget.shoutDown() # save editor config settings = ConfigManager().getSettings("APP_STATE") # clear file each time to capture opened dock tools settings.clear() settings.sync() settings.beginGroup('Editor') settings.setValue("geometry", self.saveGeometry()) settings.setValue("state", self.saveState()) settings.endGroup() # save tools state settings.beginGroup('Tools') for tool in self._tools: if isinstance(tool, ShelfTool): settings.beginGroup("ShelfTools") settings.beginGroup(tool.name()) tool.saveState(settings) settings.endGroup() settings.endGroup() if isinstance(tool, DockTool): settings.beginGroup("DockTools") settings.beginGroup(tool.uniqueName()) tool.saveState(settings) settings.endGroup() settings.endGroup() tool.onDestroy() settings.endGroup() settings.sync() # remove temp directory if exists if os.path.exists(self.currentTempDir): shutil.rmtree(self.currentTempDir) SingletonDecorator.destroyAll() PyFlow.appInstance = None QMainWindow.closeEvent(self, event)
def instance(parent=None): instance = PyFlow(parent) instance.startMainLoop() INITIALIZE() # create app folder in documents # random string used for cases when multiple instances of app are running in the same time prefs = QtCore.QSettings(ConfigManager().PREFERENCES_CONFIG_PATH, QtCore.QSettings.IniFormat) tempDirPath = prefs.value("Preferences/General/TempFilesDir") if tempDirPath == None: tempDirPath = "/tmp/pyflow" if tempDirPath[-1:] in ('/', '\\'): tempDirPath = tempDirPath[:-1] instance.currentTempDir = "{0}_{1}".format(tempDirPath, generateRandomString()) if not os.path.exists(instance.currentTempDir): os.makedirs(instance.currentTempDir) # populate tools canvas = instance.getCanvas() toolbar = instance.getToolbar() settings = QtCore.QSettings(ConfigManager().APP_SETTINGS_PATH, QtCore.QSettings.IniFormat) geo = settings.value('Editor/geometry') if geo is not None: instance.restoreGeometry(geo) state = settings.value('Editor/state') if state is not None: instance.restoreState(state) settings.beginGroup("Tools") for packageName, registeredToolSet in GET_TOOLS().items(): for ToolClass in registeredToolSet: if issubclass(ToolClass, ShelfTool): ToolInstance = ToolClass() # prevent to be garbage collected instance.registerToolInstance(ToolInstance) ToolInstance.setCanvas(canvas) action = QAction(instance) action.setIcon(ToolInstance.getIcon()) action.setText(ToolInstance.name()) action.setToolTip(ToolInstance.toolTip()) action.setObjectName(ToolInstance.name()) action.triggered.connect(ToolInstance.do) # check if context menu data available menuBuilder = ToolInstance.contextMenuBuilder() if menuBuilder: menuGenerator = ContextMenuGenerator(menuBuilder) menu = menuGenerator.generate() action.setMenu(menu) toolbar.addAction(action) # step to ShelfTools/ToolName group and pass settings inside settings.beginGroup("ShelfTools") settings.beginGroup(ToolClass.name()) ToolInstance.restoreState(settings) settings.endGroup() settings.endGroup() if issubclass(ToolClass, DockTool): menus = instance.menuBar.findChildren(QMenu) helpMenuAction = [m for m in menus if m.title() == "Help"][0].menuAction() toolsMenu = getOrCreateMenu(instance.menuBar, "Tools") instance.menuBar.insertMenu(helpMenuAction, toolsMenu) packageSubMenu = getOrCreateMenu(toolsMenu, packageName) toolsMenu.addMenu(packageSubMenu) showToolAction = packageSubMenu.addAction(ToolClass.name()) icon = ToolClass.getIcon() if icon: showToolAction.setIcon(icon) showToolAction.triggered.connect( lambda pkgName=packageName, toolName=ToolClass.name( ): instance.invokeDockToolByName(pkgName, toolName)) settings.beginGroup("DockTools") childGroups = settings.childGroups() for dockToolGroupName in childGroups: # This dock tool data been saved on last shutdown settings.beginGroup(dockToolGroupName) if dockToolGroupName in [ t.uniqueName() for t in instance._tools ]: continue toolName = dockToolGroupName.split("::")[0] ToolInstance = instance.invokeDockToolByName( packageName, toolName, settings) settings.endGroup() settings.endGroup() return instance
def instance(parent=None, software=""): assert ( software != "" ), "Invalid arguments. Please pass you software name as second argument!" instance = PyFlow(parent) settings = ConfigManager().getSettings("APP_STATE") instance.currentSoftware = software SessionDescriptor().software = instance.currentSoftware if software == "standalone": editableStyleSheet(instance) try: extraPackagePaths = [] extraPathsString = ConfigManager().getPrefsValue( "PREFS", "General/ExtraPackageDirs") if extraPathsString is not None: extraPathsString = extraPathsString.rstrip(";") extraPathsRaw = extraPathsString.split(";") for rawPath in extraPathsRaw: if os.path.exists(rawPath): extraPackagePaths.append(os.path.normpath(rawPath)) INITIALIZE(additionalPackageLocations=extraPackagePaths, software=software) except Exception as e: QMessageBox.critical(None, "Fatal error", str(e)) return instance.startMainLoop() # populate tools canvas = instance.getCanvas() toolbar = instance.getToolbar() # populate menus instance.populateMenu() geo = settings.value('Editor/geometry') if geo is not None: instance.restoreGeometry(geo) state = settings.value('Editor/state') if state is not None: instance.restoreState(state) settings.beginGroup("Tools") for packageName, registeredToolSet in GET_TOOLS().items(): for ToolClass in registeredToolSet: if issubclass(ToolClass, ShelfTool): ToolInstance = ToolClass() # prevent to be garbage collected instance.registerToolInstance(ToolInstance) ToolInstance.setAppInstance(instance) action = QAction(instance) action.setIcon(ToolInstance.getIcon()) action.setText(ToolInstance.name()) action.setToolTip(ToolInstance.toolTip()) action.setObjectName(ToolInstance.name()) action.triggered.connect(ToolInstance.do) # check if context menu data available menuBuilder = ToolInstance.contextMenuBuilder() if menuBuilder: menuGenerator = ContextMenuGenerator(menuBuilder) menu = menuGenerator.generate() action.setMenu(menu) toolbar.addAction(action) # step to ShelfTools/ToolName group and pass settings inside settings.beginGroup("ShelfTools") settings.beginGroup(ToolClass.name()) ToolInstance.restoreState(settings) settings.endGroup() settings.endGroup() if issubclass(ToolClass, DockTool): menus = instance.menuBar.findChildren(QMenu) pluginsMenuAction = [ m for m in menus if m.title() == "Plugins" ][0].menuAction() toolsMenu = getOrCreateMenu(instance.menuBar, "Tools") instance.menuBar.insertMenu(pluginsMenuAction, toolsMenu) packageSubMenu = getOrCreateMenu(toolsMenu, packageName) toolsMenu.addMenu(packageSubMenu) showToolAction = packageSubMenu.addAction(ToolClass.name()) icon = ToolClass.getIcon() if icon: showToolAction.setIcon(icon) showToolAction.triggered.connect( lambda pkgName=packageName, toolName=ToolClass.name( ): instance.invokeDockToolByName(pkgName, toolName)) settings.beginGroup("DockTools") childGroups = settings.childGroups() for dockToolGroupName in childGroups: # This dock tool data been saved on last shutdown settings.beginGroup(dockToolGroupName) if dockToolGroupName in [ t.uniqueName() for t in instance._tools ]: settings.endGroup() continue toolName = dockToolGroupName.split("::")[0] instance.invokeDockToolByName(packageName, toolName, settings) settings.endGroup() settings.endGroup() PyFlow.appInstance = instance EditorHistory().saveState("New file") for name, package in GET_PACKAGES().items(): prefsWidgets = package.PrefsWidgets() if prefsWidgets is not None: for categoryName, widgetClass in prefsWidgets.items(): PreferencesWindow().addCategory(categoryName, widgetClass()) PreferencesWindow().selectByName("General") if ConfigManager().loadedDefaults: QMessageBox.information( None, "First-time tips", "Welcome to DepthAI GUI. To use this tool efficiently, please do the following:\n\n1. Maximize the window\n2. Enable NodeBox widget (Tools > PyFlowBase > NodeBox)\n3. Enable Properties widget (Tools > PyFlowBase > Properties)\n\nHave fun!" ) return instance