def _createView(self): Logger.log("d", "Creating post processing plugin view.") ## Load all scripts in the scripts folder try: self.loadAllScripts( os.path.join( PluginRegistry.getInstance().getPluginPath( "PostProcessingPlugin"), "scripts")) except Exception as e: print( "Exception occured", e ) # TODO: Debug code (far to general catch. Remove this once done testing) path = QUrl.fromLocalFile( os.path.join( PluginRegistry.getInstance().getPluginPath( "PostProcessingPlugin"), "PostProcessingPlugin.qml")) self._component = QQmlComponent(Application.getInstance()._engine, path) # We need access to engine (although technically we can't) self._context = QQmlContext( Application.getInstance()._engine.rootContext()) self._context.setContextProperty("manager", self) self._view = self._component.create(self._context) Logger.log("d", "Post processing view created.") Application.getInstance().addAdditionalComponent( "saveButton", self._view.findChild(QObject, "postProcessingSaveAreaButton"))
def createControlInterface(self): if self._control_view is None: path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("USBPrinting"), "ControlWindow.qml")) component = QQmlComponent(Application.getInstance()._engine, path) self._control_context = QQmlContext(Application.getInstance()._engine.rootContext()) self._control_context.setContextProperty("manager", self) self._control_view = component.create(self._control_context)
def main(): app = QGuiApplication([]) try: path = QUrl(sys.argv[1]) except IndexError: print("Usage: pyqmlscene <filename>") sys.exit(1) engine = QQmlApplicationEngine() # Procedure similar to # https://github.com/qt/qtdeclarative/blob/0e9ab20b6a41bfd40aff63c9d3e686606e51e798/tools/qmlscene/main.cpp component = QQmlComponent(engine) component.loadUrl(path) root_object = component.create() if isinstance(root_object, QQuickWindow): # Display window object root_object.show() elif isinstance(root_object, QQuickItem): # Display arbitrary QQuickItems by reloading the source since # reparenting the existing root object to the view did not have any # effect. Neither does the QQuickView class have a setContent() method view = QQuickView(path) view.show() else: raise SystemExit("Error displaying {}".format(root_object)) sys.exit(app.exec_())
def view(self): with self.__view_creation_lock: if self._view is None: component = QQmlComponent(self.dice.qml_engine, self.qml_file, self) if component.status() == QQmlComponent.Error: qDebug("errors loading component: " + str(component.errors())) qDebug(self.qml_file) for error in component.errors(): qDebug(error.description()) return QQuickItem(self) # don't create the view immediately so the properties are available as soon as the view is created view = component.beginCreate(self.dice.qml_context) if view: view.setParentItem(self.dice.main_window) view.setProperty("appWindow", self.dice.app_window) view.setProperty("app", self) view.setProperty("mainWindow", self.dice.main_window) self._view = view component.completeCreate() self.view_changed.emit() else: component.completeCreate() qDebug("no view") view = QQuickItem(self) view.setParentItem(self.dice.main_window) # TODO: send an alert return view return self._view
def init_country_names_from_code(locale): '''Init the country description as found in GCompris geography/resource/board/board*.qml''' '''in the global descriptions hash''' po = None try: po = polib.pofile(gcompris_qt + '/po/gcompris_' + locale + '.po') except: print("**ERROR: Failed to load po file %s**" % ('/po/gcompris_' + locale + '.po')) print('') app = QCoreApplication(sys.argv) engine = QQmlEngine() component = QQmlComponent(engine) for qml in glob.glob(gcompris_qt + '/src/activities/geography/resource/board/*.qml'): component.loadUrl(QUrl(qml)) board = component.create() levels = board.property('levels') for level in levels.toVariant(): if 'soundFile' in level and 'toolTipText' in level: sound = level['soundFile'].split('/')[-1].replace('$CA', 'ogg') tooltip = level['toolTipText'] if po: tooltip = po.find(tooltip).msgstr if po.find( tooltip) else tooltip descriptions[sound] = tooltip
def _createCostView(self): path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("ElectricPrintCostCalculator"), "ElectricPrintCostCalculator.qml")) self._component = QQmlComponent(Application.getInstance()._engine, path) self._context = QQmlContext(Application.getInstance()._engine.rootContext()) self._context.setContextProperty("manager", self) self._cost_view = self._component.create(self._context)
def requestWrite(self, node, fileName=None, *args, **kwargs): if self._stage != OutputStage.ready: raise OutputDeviceError.DeviceBusyError() if fileName: fileName = os.path.splitext(fileName)[0] + '.gcode' else: fileName = "%s.gcode" % Application.getInstance( ).getPrintInformation().jobName self._fileName = fileName path = QUrl.fromLocalFile( os.path.join(os.path.dirname(os.path.abspath(__file__)), 'UploadFilename.qml')) self._component = QQmlComponent(Application.getInstance()._engine, path) Logger.log("d", "Errors:", self._component.errors()) self._context = QQmlContext( Application.getInstance()._engine.rootContext()) self._context.setContextProperty("manager", self) self._dialog = self._component.create(self._context) self._dialog.textChanged.connect(self.onFilenameChanged) self._dialog.accepted.connect(self.onFilenameAccepted) self._dialog.open() self._dialog.findChild(QObject, "nameField").setProperty( 'text', self._fileName) self._dialog.findChild(QObject, "nameField").select(0, len(self._fileName) - 6) self._dialog.findChild(QObject, "nameField").setProperty('focus', True)
def __init__(self, engine, parent=None): QQmlComponent.__init__(self, engine, QUrl('modules/tests/testForm/TestForm.qml'), parent) self._presenter = TestPresenter(self) self._item = self.create() self.reqReprTest.connect(self.setModel)
def _createViewFromQML(self): path = QUrl.fromLocalFile( os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), self._qml_url)) self._component = QQmlComponent(Application.getInstance()._engine, path) self._context = QQmlContext(Application.getInstance()._engine.rootContext()) self._context.setContextProperty("manager", self) self._view = self._component.create(self._context)
def init_country_names_from_code(locale): '''Init the country description as found in GCompris geography/resource/board/board*.qml''' '''in the global descriptions hash''' po = None try: po = polib.pofile( gcompris_qt + '/po/gcompris_' + locale + '.po') except: print "**ERROR: Failed to load po file %s**" %(gcompris_qt + '/po/gcompris_' + locale + '.po') print '' app = QCoreApplication(sys.argv) engine = QQmlEngine() component = QQmlComponent(engine) for qml in glob.glob(gcompris_qt + '/src/activities/geography/resource/board/*.qml'): component.loadUrl(QUrl(qml)) board = component.create() levels = board.property('levels') for level in levels.toVariant(): if level.has_key('soundFile') and level.has_key('toolTipText'): sound = level['soundFile'].split('/')[-1].replace('$CA', 'ogg') tooltip = level['toolTipText'] if po: tooltip = po.find(tooltip).msgstr if po.find(tooltip) else tooltip descriptions[sound] = tooltip
def createChangelogWindow(self): path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "ChangeLog.qml")) component = QQmlComponent(Application.getInstance()._engine, path) self._changelog_context = QQmlContext(Application.getInstance()._engine.rootContext()) self._changelog_context.setContextProperty("manager", self) self._changelog_window = component.create(self._changelog_context)
def _createAdditionalComponentsView(self): Logger.log("d", "Creating additional ui components for UM3.") path = QUrl.fromLocalFile( os.path.join( PluginRegistry.getInstance().getPluginPath( "UM3NetworkPrinting"), "UM3InfoComponents.qml")) self.__additional_component = QQmlComponent( Application.getInstance()._engine, path) # We need access to engine (although technically we can't) self.__additional_components_context = QQmlContext( Application.getInstance()._engine.rootContext()) self.__additional_components_context.setContextProperty( "manager", self) self.__additional_components_view = self.__additional_component.create( self.__additional_components_context) if not self.__additional_components_view: Logger.log("w", "Could not create ui components for UM3.") return Application.getInstance().addAdditionalComponent( "monitorButtons", self.__additional_components_view.findChild( QObject, "networkPrinterConnectButton")) Application.getInstance().addAdditionalComponent( "machinesDetailPane", self.__additional_components_view.findChild( QObject, "networkPrinterConnectionInfo"))
def _createAdditionalComponentsView(self): Logger.log( "d", "Creating additional ui components for Pause Backend plugin.") path = QUrl.fromLocalFile( os.path.join( PluginRegistry.getInstance().getPluginPath( "PauseBackendPlugin"), "PauseBackend.qml")) self._additional_component = QQmlComponent( Application.getInstance()._engine, path) # We need access to engine (although technically we can't) self._additional_components_context = QQmlContext( Application.getInstance()._engine.rootContext()) self._additional_components_context.setContextProperty("manager", self) self._additional_components_view = self._additional_component.create( self._additional_components_context) if not self._additional_components_view: Logger.log( "w", "Could not create additional components for Pause Backend plugin." ) return Application.getInstance().addAdditionalComponent( "saveButton", self._additional_components_view.findChild(QObject, "pauseResumeButton"))
def createQmlComponent( self, qml_file_path: str, context_properties: Dict[str, "QObject"] = None) -> Optional["QObject"]: if self._qml_engine is None: # Protect in case the engine was not initialized yet return None path = QUrl.fromLocalFile(qml_file_path) component = QQmlComponent(self._qml_engine, path) result_context = QQmlContext( self._qml_engine.rootContext() ) #type: ignore #MyPy doens't realise that self._qml_engine can't be None here. if context_properties is not None: for name, value in context_properties.items(): result_context.setContextProperty(name, value) result = component.create(result_context) for err in component.errors(): Logger.log("e", str(err.toString())) if result is None: return None # We need to store the context with the qml object, else the context gets garbage collected and the qml objects # no longer function correctly/application crashes. result.attached_context = result_context return result
def _createAdditionalComponentsView(self): Logger.log( "d", "Creating additional ui components for OctoPrint-connected printers." ) path = QUrl.fromLocalFile( os.path.join(os.path.dirname(os.path.abspath(__file__)), "OctoPrintComponents.qml")) self._additional_component = QQmlComponent( Application.getInstance()._engine, path) # We need access to engine (although technically we can't) self._additional_components_context = QQmlContext( Application.getInstance()._engine.rootContext()) self._additional_components_context.setContextProperty("manager", self) self._additional_components_view = self._additional_component.create( self._additional_components_context) if not self._additional_components_view: Logger.log( "w", "Could not create additional components for OctoPrint-connected printers." ) return Application.getInstance().addAdditionalComponent( "monitorButtons", self._additional_components_view.findChild(QObject, "openOctoPrintButton"))
def createQmlComponent(self, qml_file_path: str, context_properties: Dict[str, "QObject"] = None) -> Optional["QObject"]: """Create a QML component from a qml file. :param qml_file_path:: The absolute file path to the root qml file. :param context_properties:: Optional dictionary containing the properties that will be set on the context of the qml instance before creation. :return: None in case the creation failed (qml error), else it returns the qml instance. :note If the creation fails, this function will ensure any errors are logged to the logging service. """ if self._qml_engine is None: # Protect in case the engine was not initialized yet return None path = QUrl.fromLocalFile(qml_file_path) component = QQmlComponent(self._qml_engine, path) result_context = QQmlContext(self._qml_engine.rootContext()) #type: ignore #MyPy doens't realise that self._qml_engine can't be None here. if context_properties is not None: for name, value in context_properties.items(): result_context.setContextProperty(name, value) result = component.create(result_context) for err in component.errors(): Logger.log("e", str(err.toString())) if result is None: return None # We need to store the context with the qml object, else the context gets garbage collected and the qml objects # no longer function correctly/application crashes. result.attached_context = result_context return result
def loadBook(self, filename): self.last_book = filename self.filename = "" engine = QQmlEngine() self.component = QQmlComponent(engine) self.component.statusChanged.connect(self.loadStatusChanged) self.component.loadUrl(QUrl.fromLocalFile(filename))
def _createAdditionalComponentsView(self): Logger.log( "d", "Creating additional ui components for OctoPrint-connected printers." ) path = QUrl.fromLocalFile( os.path.join( PluginRegistry.getInstance().getPluginPath( "SculptoPrintPlugin"), "SculptoPrintPlugin.qml")) self._additional_component = QQmlComponent( Application.getInstance()._engine, path) # We need access to engine (although technically we can't) self._additional_components_context = QQmlContext( Application.getInstance()._engine.rootContext()) self._additional_components_context.setContextProperty("manager", self) self._additional_components_view = self._additional_component.create( self._additional_components_context) if not self._additional_components_view: Logger.log( "w", "Could not create additional components for OctoPrint-connected printers." ) return
def _createAdditionalComponentsView(self): Logger.log( "d", "Creating additional ui components for Repetier-Server - connected printers." ) path = QUrl.fromLocalFile( os.path.join( PluginRegistry.getInstance().getPluginPath( "RepetierServerPlugin"), "RepetierServerComponents.qml")) self._additional_component = QQmlComponent( Application.getInstance()._engine, path) # We need access to engine (although technically we can't) self._additional_components_context = QQmlContext( Application.getInstance()._engine.rootContext()) self._additional_components_context.setContextProperty("manager", self) self._additional_components_view = self._additional_component.create( self._additional_components_context) if not self._additional_components_view: Logger.log( "w", "Could not create additional components for Repetier-Server - connected printers." ) return Application.getInstance().addAdditionalComponent( "monitorButtons", self._additional_components_view.findChild( QObject, "openRepetierServerButton"))
def createControlInterface(self): if self._control_view is None: Logger.log("d", "Creating control interface for printer connection") path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("USBPrinting"), "ControlWindow.qml")) component = QQmlComponent(Application.getInstance()._engine, path) self._control_context = QQmlContext(Application.getInstance()._engine.rootContext()) self._control_context.setContextProperty("manager", self) self._control_view = component.create(self._control_context)
def spawnFirmwareInterface(self, serial_port): if self._firmware_view is None: path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("Doodle3D"), "SettingsWindow.qml")) component = QQmlComponent(Application.getInstance()._engine, path) self._firmware_context = QQmlContext(Application.getInstance()._engine.rootContext()) self._firmware_context.setContextProperty("manager", self) self._firmware_view = component.create(self._firmware_context) self._firmware_view.show()
def _createViewFromQML(self): path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("3MFReader"), self._qml_url)) self._component = QQmlComponent(Application.getInstance()._engine, path) self._context = QQmlContext(Application.getInstance()._engine.rootContext()) self._context.setContextProperty("manager", self) self._view = self._component.create(self._context) if self._view is None: Logger.log("c", "QQmlComponent status %s", self._component.status()) Logger.log("c", "QQmlComponent error string %s", self._component.errorString())
def _createConfigUI(self): if self._ui_view is None: path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("CuraSolidWorksPlugin"), "ExportSTLUI.qml")) component = QQmlComponent(Application.getInstance()._engine, path) self._ui_context = QQmlContext(Application.getInstance()._engine.rootContext()) self._ui_context.setContextProperty("manager", self) self._ui_view = component.create(self._ui_context) self._ui_view.setFlags(self._ui_view.flags() & ~Qt.WindowCloseButtonHint & ~Qt.WindowMinimizeButtonHint & ~Qt.WindowMaximizeButtonHint)
def createChangelogWindow(self): path = QUrl.fromLocalFile( os.path.join( PluginRegistry.getInstance().getPluginPath("ChangeLogPlugin"), "ChangeLog.qml")) component = QQmlComponent(Application.getInstance()._engine, path) self._changelog_context = QQmlContext( Application.getInstance()._engine.rootContext()) self._changelog_context.setContextProperty("manager", self) self._changelog_window = component.create(self._changelog_context)
def _createView(self): ## Load all scripts in the scripts folder self.loadAllScripts(os.path.join(PluginRegistry.getInstance().getPluginPath("PostProcessingPlugin"), "scripts")) path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("PostProcessingPlugin"), "PostProcessingPlugin.qml")) self._component = QQmlComponent(Application.getInstance()._engine, path) self._context = QQmlContext(Application.getInstance()._engine.rootContext()) self._context.setContextProperty("manager", self) self._view = self._component.create(self._context)
def spawnFirmwareInterface(self, serial_port): if self._firmware_view is None: path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("USBPrinting"), "FirmwareUpdateWindow.qml")) component = QQmlComponent(Application.getInstance()._engine, path) self._firmware_context = QQmlContext(Application.getInstance()._engine.rootContext()) self._firmware_context.setContextProperty("manager", self) self._firmware_view = component.create(self._firmware_context) self._firmware_view.show()
def view(self): with self.__view_creation_lock: if self._view is None: component = QQmlComponent(self.dice.qml_engine, self.qml_file, self) if component.status() == QQmlComponent.Error: qDebug("errors loading component: "+str(component.errors())) qDebug(self.qml_file) for error in component.errors(): qDebug(error.description()) return QQuickItem(self) # don't create the view immediately so the properties are available as soon as the view is created view = component.beginCreate(self.dice.qml_context) if view: view.setParentItem(self.dice.main_window) view.setProperty("appWindow", self.dice.app_window) view.setProperty("app", self) view.setProperty("mainWindow", self.dice.main_window) self._view = view component.completeCreate() self.view_changed.emit() else: component.completeCreate() qDebug("no view") view = QQuickItem(self) view.setParentItem(self.dice.main_window) # TODO: send an alert return view return self._view
def createUserAgreementWindow(self): path = QUrl.fromLocalFile( os.path.join( PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "UserAgreement.qml")) component = QQmlComponent(Application.getInstance()._engine, path) self._user_agreement_context = QQmlContext( Application.getInstance()._engine.rootContext()) self._user_agreement_context.setContextProperty("manager", self) self._user_agreement_window = component.create( self._user_agreement_context)
def _createConfigUI(self): if self._ui_view is None: Logger.log("d", "Creating ImageReader config UI") path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("ImageReader"), "ConfigUI.qml")) component = QQmlComponent(Application.getInstance()._engine, path) self._ui_context = QQmlContext(Application.getInstance()._engine.rootContext()) self._ui_context.setContextProperty("manager", self) self._ui_view = component.create(self._ui_context) self._ui_view.setFlags(self._ui_view.flags() & ~Qt.WindowCloseButtonHint & ~Qt.WindowMinimizeButtonHint & ~Qt.WindowMaximizeButtonHint); self._disable_size_callbacks = False
def _createDialogue(self): #Create a QML component from the Hello.qml file. qml_file = QUrl.fromLocalFile( os.path.join( PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "SelectionInfo.qml")) component = QQmlComponent(Application.getInstance()._engine, qml_file) qml_context = QQmlContext( Application.getInstance()._engine.rootContext( )) #List the QML component as subcomponent of the main window. return component.create(qml_context)
def _createDialog(self): Logger.log("d", "PluginBrowser") path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "PluginBrowser.qml")) self._qml_component = QQmlComponent(Application.getInstance()._engine, path) # We need access to engine (although technically we can't) self._qml_context = QQmlContext(Application.getInstance()._engine.rootContext()) self._qml_context.setContextProperty("manager", self) self._dialog = self._qml_component.create(self._qml_context) if self._dialog is None: Logger.log("e", "QQmlComponent status %s", self._qml_component.status()) Logger.log("e", "QQmlComponent errorString %s", self._qml_component.errorString())
def __init__(self) : QObject.__init__( self ) self.app = QApplication( sys.argv ) self.app.setApplicationName( 'Waterfall' ) engine = QQmlEngine() appDirPath = os.path.dirname( os.path.abspath( __file__ ) ) rootContext = engine.rootContext() rootContext.setContextProperty( 'controller', self ) rootContext.setContextProperty( 'appPath', appDirPath.replace( "\\", "/" ) + "/" ) windowComp = QQmlComponent( engine, QUrl( 'qml/Main.qml' ) ) self.window = windowComp.create() self.window.show() self.app.exec()
def spawnPrintView(self): if self._print_view is None: path = QUrl.fromLocalFile(os.path.join(self._plugin_path, "PrintWindow.qml")) component = QQmlComponent(Application.getInstance()._engine, path) self._print_context = QQmlContext(Application.getInstance()._engine.rootContext()) self._print_context.setContextProperty("OutputDevice", self) self._print_view = component.create(self._print_context) if component.isError(): Logger.log("e", " Errors creating component: \n%s", "\n".join( [e.toString() for e in component.errors()])) if self._print_view is not None: self._print_view.show()
def _createMonitorViewFromQML(self): path = QUrl.fromLocalFile(self._monitor_view_qml_path) # Because of garbage collection we need to keep this referenced by python. self._monitor_component = QQmlComponent(Application.getInstance()._engine, path) # Check if the context was already requested before (Printer output device might have multiple items in the future) if self._qml_context is None: self._qml_context = QQmlContext(Application.getInstance()._engine.rootContext()) self._qml_context.setContextProperty("OutputDevice", self) self._monitor_item = self._monitor_component.create(self._qml_context) if self._monitor_item is None: Logger.log("e", "QQmlComponent status %s", self._monitor_component.status()) Logger.log("e", "QQmlComponent error string %s", self._monitor_component.errorString())
class DialogHandler(QObject, Extension): def __init__(self, parent=None): super().__init__(parent) self._config_dialog = None self._tutorial_dialog = None self.addMenuItem(i18n_catalog.i18n("Configure"), self._openConfigDialog) self.addMenuItem( i18n_catalog.i18n("How to install Cura SolidWorks macro"), self._openTutorialDialog) def _openConfigDialog(self): if not self._config_dialog: self._config_dialog = self._createDialog("ConfigDialog.qml") self._config_dialog.show() def _openTutorialDialog(self): if not self._tutorial_dialog: self._tutorial_dialog = self._createDialog( "MacroTutorialDialog.qml") self._tutorial_dialog.show() def _createDialog(self, dialog_qml): path = QUrl.fromLocalFile( os.path.join( PluginRegistry.getInstance().getPluginPath(self.getPluginId()), dialog_qml)) self._qml_component = QQmlComponent(Application.getInstance()._engine, path) # We need access to engine (although technically we can't) self._qml_context = QQmlContext( Application.getInstance()._engine.rootContext()) self._qml_context.setContextProperty("manager", self) dialog = self._qml_component.create(self._qml_context) if dialog is None: Logger.log("e", "QQmlComponent status %s", self._qml_component.status()) Logger.log("e", "QQmlComponent errorString %s", self._qml_component.errorString()) return dialog @pyqtSlot() def openMacroAndIconDirectory(self): plugin_dir = os.path.join(PluginRegistry.getInstance().getPluginPath( self.getPluginId())) macro_dir = os.path.join(plugin_dir, "macro") os.system("explorer.exe \"%s\"" % macro_dir)
def get_geography_on_letter_from_code(): '''Return all the countries in geography/resource/board/board-x.json''' words = set() app = QCoreApplication(sys.argv) engine = QQmlEngine() component = QQmlComponent(engine) for qml in glob.glob(gcompris_qt + '/src/activities/geography/resource/board/*.qml'): component.loadUrl(QUrl(qml)) board = component.create() levels = board.property('levels') for level in levels.toVariant(): if level.has_key('soundFile') and (not level.has_key('type') or level['type'] != "SHAPE_BACKGROUND"): sound = level['soundFile'].split('/')[-1].replace('$CA', 'ogg') words.add(sound) return words
def createQmlComponent(self, qml_file_path: str, context_properties: Dict[str, "QObject"] = None) -> Optional["QObject"]: if self._qml_engine is None: # Protect in case the engine was not initialized yet return None path = QUrl.fromLocalFile(qml_file_path) component = QQmlComponent(self._qml_engine, path) result_context = QQmlContext(self._qml_engine.rootContext()) #type: ignore #MyPy doens't realise that self._qml_engine can't be None here. if context_properties is not None: for name, value in context_properties.items(): result_context.setContextProperty(name, value) result = component.create(result_context) for err in component.errors(): Logger.log("e", str(err.toString())) if result is None: return None # We need to store the context with the qml object, else the context gets garbage collected and the qml objects # no longer function correctly/application crashes. result.attached_context = result_context return result
def _createAdditionalComponentsView(self): Logger.log("d", "Creating additional ui components for Pause Backend plugin.") path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("PauseBackendPlugin"), "PauseBackend.qml")) self._additional_component = QQmlComponent(Application.getInstance()._engine, path) # We need access to engine (although technically we can't) self._additional_components_context = QQmlContext(Application.getInstance()._engine.rootContext()) self._additional_components_context.setContextProperty("manager", self) self._additional_components_view = self._additional_component.create(self._additional_components_context) if not self._additional_components_view: Logger.log("w", "Could not create additional components for Pause Backend plugin.") return Application.getInstance().addAdditionalComponent("saveButton", self._additional_components_view.findChild(QObject, "pauseResumeButton"))
def _createView(self): Logger.log("d", "Creating post processing plugin view.") ## Load all scripts in the scripts folder try: self.loadAllScripts(os.path.join(PluginRegistry.getInstance().getPluginPath("PostProcessingPlugin"), "scripts")) except Exception as e: print("Exception occured", e) # TODO: Debug code (far to general catch. Remove this once done testing) path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("PostProcessingPlugin"), "PostProcessingPlugin.qml")) self._component = QQmlComponent(Application.getInstance()._engine, path) # We need access to engine (although technically we can't) self._context = QQmlContext(Application.getInstance()._engine.rootContext()) self._context.setContextProperty("manager", self) self._view = self._component.create(self._context) Logger.log("d", "Post processing view created.")
class PauseBackend(QObject, Extension): def __init__(self, parent = None): super().__init__(parent = parent) self._additional_component = None self._additional_components_view = None Application.getInstance().engineCreatedSignal.connect(self._createAdditionalComponentsView) def _createAdditionalComponentsView(self): Logger.log("d", "Creating additional ui components for Pause Backend plugin.") path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("PauseBackendPlugin"), "PauseBackend.qml")) self._additional_component = QQmlComponent(Application.getInstance()._engine, path) # We need access to engine (although technically we can't) self._additional_components_context = QQmlContext(Application.getInstance()._engine.rootContext()) self._additional_components_context.setContextProperty("manager", self) self._additional_components_view = self._additional_component.create(self._additional_components_context) if not self._additional_components_view: Logger.log("w", "Could not create additional components for Pause Backend plugin.") return Application.getInstance().addAdditionalComponent("saveButton", self._additional_components_view.findChild(QObject, "pauseResumeButton")) @pyqtSlot() def pauseBackend(self): backend = Application.getInstance().getBackend() backend._change_timer.timeout.disconnect(backend.slice) backend._terminate() backend.backendStateChange.emit(BackendState.Error) @pyqtSlot() def resumeBackend(self): backend = Application.getInstance().getBackend() backend._change_timer.timeout.connect(backend.slice) backend.forceSlice()
def _createAdditionalComponentsView(self): Logger.log("d", "Creating additional ui components for UM3.") path = QUrl.fromLocalFile( os.path.join(PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), "UM3InfoComponents.qml") ) self.__additional_component = QQmlComponent(Application.getInstance()._engine, path) # We need access to engine (although technically we can't) self.__additional_components_context = QQmlContext(Application.getInstance()._engine.rootContext()) self.__additional_components_context.setContextProperty("manager", self) self.__additional_components_view = self.__additional_component.create(self.__additional_components_context) if not self.__additional_components_view: Logger.log("w", "Could not create ui components for UM3.") return Application.getInstance().addAdditionalComponent( "monitorButtons", self.__additional_components_view.findChild(QObject, "networkPrinterConnectButton") ) Application.getInstance().addAdditionalComponent( "machinesDetailPane", self.__additional_components_view.findChild(QObject, "networkPrinterConnectionInfo") )
def main(): # Set up correct Ctrl-C behavior. signal.signal(signal.SIGINT, signal.SIG_DFL) app = QGuiApplication( sys.argv ) engine = QQmlEngine() engine.addImportPath( path.join( path.dirname( __file__ ), 'ui', 'qml' ) ) core.register_types() component = QQmlComponent( engine ) component.loadUrl( QUrl( '/home/feoh3/.config/nube/hud.qml' ) ) if component.isError(): print( "\n".join( error.toString() for error in component.errors() ) ) else: window = component.create() app.exec_()
class WorkspaceDialog(QObject): showDialogSignal = pyqtSignal() def __init__(self, parent = None): super().__init__(parent) self._component = None self._context = None self._view = None self._qml_url = "WorkspaceDialog.qml" self._lock = threading.Lock() self._default_strategy = "override" self._result = {"machine": self._default_strategy, "quality_changes": self._default_strategy, "definition_changes": self._default_strategy, "material": self._default_strategy} self._visible = False self.showDialogSignal.connect(self.__show) self._has_quality_changes_conflict = False self._has_definition_changes_conflict = False self._has_machine_conflict = False self._has_material_conflict = False self._num_visible_settings = 0 self._num_user_settings = 0 self._active_mode = "" self._quality_name = "" self._num_settings_overriden_by_quality_changes = 0 self._quality_type = "" self._machine_name = "" self._machine_type = "" self._variant_type = "" self._material_labels = [] self._extruders = [] self._objects_on_plate = False machineConflictChanged = pyqtSignal() qualityChangesConflictChanged = pyqtSignal() definitionChangesConflictChanged = pyqtSignal() materialConflictChanged = pyqtSignal() numVisibleSettingsChanged = pyqtSignal() activeModeChanged = pyqtSignal() qualityNameChanged = pyqtSignal() numSettingsOverridenByQualityChangesChanged = pyqtSignal() qualityTypeChanged = pyqtSignal() machineNameChanged = pyqtSignal() materialLabelsChanged = pyqtSignal() objectsOnPlateChanged = pyqtSignal() numUserSettingsChanged = pyqtSignal() machineTypeChanged = pyqtSignal() variantTypeChanged = pyqtSignal() extrudersChanged = pyqtSignal() @pyqtProperty(str, notify=variantTypeChanged) def variantType(self): return self._variant_type def setVariantType(self, variant_type): if self._variant_type != variant_type: self._variant_type = variant_type self.variantTypeChanged.emit() @pyqtProperty(str, notify=machineTypeChanged) def machineType(self): return self._machine_type def setMachineType(self, machine_type): self._machine_type = machine_type self.machineTypeChanged.emit() def setNumUserSettings(self, num_user_settings): if self._num_user_settings != num_user_settings: self._num_user_settings = num_user_settings self.numVisibleSettingsChanged.emit() @pyqtProperty(int, notify=numUserSettingsChanged) def numUserSettings(self): return self._num_user_settings @pyqtProperty(bool, notify=objectsOnPlateChanged) def hasObjectsOnPlate(self): return self._objects_on_plate def setHasObjectsOnPlate(self, objects_on_plate): if self._objects_on_plate != objects_on_plate: self._objects_on_plate = objects_on_plate self.objectsOnPlateChanged.emit() @pyqtProperty("QVariantList", notify = materialLabelsChanged) def materialLabels(self): return self._material_labels def setMaterialLabels(self, material_labels): if self._material_labels != material_labels: self._material_labels = material_labels self.materialLabelsChanged.emit() @pyqtProperty("QVariantList", notify=extrudersChanged) def extruders(self): return self._extruders def setExtruders(self, extruders): if self._extruders != extruders: self._extruders = extruders self.extrudersChanged.emit() @pyqtProperty(str, notify = machineNameChanged) def machineName(self): return self._machine_name def setMachineName(self, machine_name): if self._machine_name != machine_name: self._machine_name = machine_name self.machineNameChanged.emit() @pyqtProperty(str, notify=qualityTypeChanged) def qualityType(self): return self._quality_type def setQualityType(self, quality_type): if self._quality_type != quality_type: self._quality_type = quality_type self.qualityTypeChanged.emit() @pyqtProperty(int, notify=numSettingsOverridenByQualityChangesChanged) def numSettingsOverridenByQualityChanges(self): return self._num_settings_overriden_by_quality_changes def setNumSettingsOverridenByQualityChanges(self, num_settings_overriden_by_quality_changes): self._num_settings_overriden_by_quality_changes = num_settings_overriden_by_quality_changes self.numSettingsOverridenByQualityChangesChanged.emit() @pyqtProperty(str, notify=qualityNameChanged) def qualityName(self): return self._quality_name def setQualityName(self, quality_name): if self._quality_name != quality_name: self._quality_name = quality_name self.qualityNameChanged.emit() @pyqtProperty(str, notify=activeModeChanged) def activeMode(self): return self._active_mode def setActiveMode(self, active_mode): if active_mode == 0: self._active_mode = i18n_catalog.i18nc("@title:tab", "Recommended") else: self._active_mode = i18n_catalog.i18nc("@title:tab", "Custom") self.activeModeChanged.emit() @pyqtProperty(int, constant = True) def totalNumberOfSettings(self): return len(ContainerRegistry.getInstance().findDefinitionContainers(id="fdmprinter")[0].getAllKeys()) @pyqtProperty(int, notify = numVisibleSettingsChanged) def numVisibleSettings(self): return self._num_visible_settings def setNumVisibleSettings(self, num_visible_settings): if self._num_visible_settings != num_visible_settings: self._num_visible_settings = num_visible_settings self.numVisibleSettingsChanged.emit() @pyqtProperty(bool, notify = machineConflictChanged) def machineConflict(self): return self._has_machine_conflict @pyqtProperty(bool, notify=qualityChangesConflictChanged) def qualityChangesConflict(self): return self._has_quality_changes_conflict @pyqtProperty(bool, notify=definitionChangesConflictChanged) def definitionChangesConflict(self): return self._has_definition_changes_conflict @pyqtProperty(bool, notify=materialConflictChanged) def materialConflict(self): return self._has_material_conflict @pyqtSlot(str, str) def setResolveStrategy(self, key, strategy): if key in self._result: self._result[key] = strategy ## Close the backend: otherwise one could end up with "Slicing..." @pyqtSlot() def closeBackend(self): Application.getInstance().getBackend().close() def setMaterialConflict(self, material_conflict): if self._has_material_conflict != material_conflict: self._has_material_conflict = material_conflict self.materialConflictChanged.emit() def setMachineConflict(self, machine_conflict): if self._has_machine_conflict != machine_conflict: self._has_machine_conflict = machine_conflict self.machineConflictChanged.emit() def setQualityChangesConflict(self, quality_changes_conflict): if self._has_quality_changes_conflict != quality_changes_conflict: self._has_quality_changes_conflict = quality_changes_conflict self.qualityChangesConflictChanged.emit() def setDefinitionChangesConflict(self, definition_changes_conflict): if self._has_definition_changes_conflict != definition_changes_conflict: self._has_definition_changes_conflict = definition_changes_conflict self.definitionChangesConflictChanged.emit() def getResult(self): if "machine" in self._result and not self._has_machine_conflict: self._result["machine"] = None if "quality_changes" in self._result and not self._has_quality_changes_conflict: self._result["quality_changes"] = None if "definition_changes" in self._result and not self._has_definition_changes_conflict: self._result["definition_changes"] = None if "material" in self._result and not self._has_material_conflict: self._result["material"] = None return self._result def _createViewFromQML(self): path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("3MFReader"), self._qml_url)) self._component = QQmlComponent(Application.getInstance()._engine, path) self._context = QQmlContext(Application.getInstance()._engine.rootContext()) self._context.setContextProperty("manager", self) self._view = self._component.create(self._context) if self._view is None: Logger.log("c", "QQmlComponent status %s", self._component.status()) Logger.log("c", "QQmlComponent error string %s", self._component.errorString()) def show(self): # Emit signal so the right thread actually shows the view. if threading.current_thread() != threading.main_thread(): self._lock.acquire() # Reset the result self._result = {"machine": self._default_strategy, "quality_changes": self._default_strategy, "definition_changes": self._default_strategy, "material": self._default_strategy} self._visible = True self.showDialogSignal.emit() @pyqtSlot() ## Used to notify the dialog so the lock can be released. def notifyClosed(self): self._result = {} self._visible = False self._lock.release() def hide(self): self._visible = False self._lock.release() self._view.hide() @pyqtSlot() def onOkButtonClicked(self): self._view.hide() self.hide() @pyqtSlot() def onCancelButtonClicked(self): self._view.hide() self.hide() self._result = {} ## Block thread until the dialog is closed. def waitForClose(self): if self._visible: if threading.current_thread() != threading.main_thread(): self._lock.acquire() self._lock.release() else: # If this is not run from a separate thread, we need to ensure that the events are still processed. while self._visible: time.sleep(1 / 50) QCoreApplication.processEvents() # Ensure that the GUI does not freeze. def __show(self): if self._view is None: self._createViewFromQML() if self._view: self._view.show()
class PostProcessingPlugin(QObject, Extension): def __init__(self, parent = None): super().__init__(parent) self.addMenuItem(i18n_catalog.i18n("Modify G-Code"), self.showPopup) self._view = None # Loaded scripts are all scripts that can be used self._loaded_scripts = {} self._script_labels = {} # Script list contains instances of scripts in loaded_scripts. There can be duplicates and they will be executed in sequence. self._script_list = [] self._selected_script_index = 0 @pyqtSlot(int, result = "QVariant") def getSettingModel(self, index): return self._script_list[index].getSettingsModel() @pyqtSlot(str, "QVariant") ## Called when the setting is changed. def setSettingValue(self, key, value): setting = self._script_list[self._selected_script_index].getSettings().getSettingByKey(key) if setting: setting.setValue(value) #self._script_list[self._selected_script_index].getSettings().setSettingValue selectedIndexChanged = pyqtSignal() @pyqtProperty("QVariant", notify = selectedIndexChanged) def selectedScriptSettingsModel(self): try: return self._script_list[self._selected_script_index].getSettingsModel() except: return None @pyqtSlot() def execute(self): scene = Application.getInstance().getController().getScene() if hasattr(scene, "gcode_list"): gcode_list = getattr(scene, "gcode_list") if gcode_list: for script in self._script_list: try: gcode_list = script.execute(gcode_list) except Exception as e: print(e) pass setattr(scene, "gcode_list", gcode_list) @pyqtSlot(int) def setSelectedScriptIndex(self, index): self._selected_script_index = index self.selectedIndexChanged.emit() @pyqtProperty(int, notify = selectedIndexChanged) def selectedScriptIndex(self): return self._selected_script_index @pyqtSlot(int, int) def moveScript(self, index, new_index): if new_index < 0 or new_index > len(self._script_list)-1: return #nothing needs to be done else: # Magical switch code. self._script_list[new_index], self._script_list[index] = self._script_list[index], self._script_list[new_index] self.scriptListChanged.emit() self.selectedIndexChanged.emit() #Ensure that settings are updated ## Remove a script from the active script list by index. @pyqtSlot(int) def removeScriptByIndex(self, index): self._script_list.pop(index) if len(self._script_list) - 1 < self._selected_script_index: self._selected_script_index = len(self._script_list) - 1 self.scriptListChanged.emit() self.selectedIndexChanged.emit() #Ensure that settings are updated ## Load all scripts from provided path. This should probably only be done on init. def loadAllScripts(self, path): scripts = pkgutil.iter_modules(path = [path]) for loader, script_name, ispkg in scripts: if script_name not in sys.modules: # Import module loaded_script = __import__("PostProcessingPlugin.scripts."+ script_name, fromlist = [script_name]) loaded_class = getattr(loaded_script, script_name) temp_object = loaded_class() try: setting_data = temp_object.getSettingData() if "label" in setting_data and "key" in setting_data: self._script_labels[setting_data["key"]] = setting_data["label"] self._loaded_scripts[setting_data["key"]] = loaded_class else: Logger.log("w", "Script %s.py has no label or key", script_name) self._script_labels[script_name] = script_name self._loaded_scripts[script_name] = loaded_class #self._script_list.append(loaded_class()) self.loadedScriptListChanged.emit() except AttributeError: Logger.log("e", "Script %s.py is not a recognised script type. Ensure it inherits Script", script_name) except NotImplementedError: Logger.log("e", "Script %s.py has no implemented settings",script_name) loadedScriptListChanged = pyqtSignal() @pyqtProperty("QVariantList", notify = loadedScriptListChanged) def loadedScriptList(self): return list(self._loaded_scripts.keys()) @pyqtSlot(str, result = str) def getScriptLabelByKey(self, key): return self._script_labels[key] scriptListChanged = pyqtSignal() @pyqtProperty("QVariantList", notify = scriptListChanged) def scriptList(self): script_list = [script.getSettingData()["key"] for script in self._script_list] return script_list @pyqtSlot(str) def addScriptToList(self, key): self._script_list.append(self._loaded_scripts[key]()) self.setSelectedScriptIndex(len(self._script_list) - 1) self.scriptListChanged.emit() ## Creates the view used by show popup. The view is saved because of the fairly aggressive garbage collection. def _createView(self): ## Load all scripts in the scripts folder self.loadAllScripts(os.path.join(PluginRegistry.getInstance().getPluginPath("PostProcessingPlugin"), "scripts")) path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("PostProcessingPlugin"), "PostProcessingPlugin.qml")) self._component = QQmlComponent(Application.getInstance()._engine, path) self._context = QQmlContext(Application.getInstance()._engine.rootContext()) self._context.setContextProperty("manager", self) self._view = self._component.create(self._context) ## Show the (GUI) popup of the post processing plugin. def showPopup(self): if self._view is None: self._createView() self._view.show()
app = QCoreApplication(sys.argv) qmlRegisterType(BirthdayPartyAttached) qmlRegisterType(BirthdayParty, "People", 1, 0, "BirthdayParty", attachedProperties=BirthdayPartyAttached) qmlRegisterType(HappyBirthdaySong, "People", 1, 0, "HappyBirthdaySong") qmlRegisterType(ShoeDescription) qmlRegisterType(Person) qmlRegisterType(Boy, "People", 1, 0, "Boy") qmlRegisterType(Girl, "People", 1, 0, "Girl") engine = QQmlEngine() component = QQmlComponent(engine) component.setData(QML, QUrl()) party = component.create() if party is not None and party.host is not None: print("\"%s\" is having a birthday!" % party.host.name) if isinstance(party.host, Boy): print("He is inviting:") else: print("She is inviting:") for guest in party.guests: attached = qmlAttachedPropertiesObject(BirthdayParty, guest, False)
# Show the Label appLabel.show() # Create a QML engine. engine = QQmlEngine() # Initialize PhotoBoothEngine. pbengine = PhotoBoothEngine() pbengine.on_status.connect(appLabel.rootObject().status) pbengine.on_update_filter_preview.connect(appLabel.rootObject().updateImageFilterPreview) appLabel.rootContext().setContextProperty('pbengine', pbengine) # Create a component factory and load the QML script. print("Hello") component = QQmlComponent(appLabel.engine()) component.loadUrl(QUrl('TextStatusFly.qml')) print("Hello2") asdf = component.create(appLabel.rootContext()) print("Hello3") asdf.setParentItem(appLabel.rootObject()) asdf.setParent(appLabel.rootObject()) print("Hello4") #asdf.setProperty("targetX", 100) asdf.setProperty("objectName", "textStatusBar") print("Hello5") appLabel.rootContext().setContextProperty('textStatusBar', asdf)
class WorkspaceDialog(QObject): showDialogSignal = pyqtSignal() def __init__(self, parent = None): super().__init__(parent) self._component = None self._context = None self._view = None self._qml_url = "WorkspaceDialog.qml" self._lock = threading.Lock() self._default_strategy = "override" self._result = {"machine": self._default_strategy, "quality_changes": self._default_strategy, "material": self._default_strategy} self._visible = False self.showDialogSignal.connect(self.__show) self._has_quality_changes_conflict = False self._has_machine_conflict = False self._has_material_conflict = False machineConflictChanged = pyqtSignal() qualityChangesConflictChanged = pyqtSignal() materialConflictChanged = pyqtSignal() @pyqtProperty(bool, notify = machineConflictChanged) def machineConflict(self): return self._has_machine_conflict @pyqtProperty(bool, notify=qualityChangesConflictChanged) def qualityChangesConflict(self): return self._has_quality_changes_conflict @pyqtProperty(bool, notify=materialConflictChanged) def materialConflict(self): return self._has_material_conflict @pyqtSlot(str, str) def setResolveStrategy(self, key, strategy): if key in self._result: self._result[key] = strategy def setMaterialConflict(self, material_conflict): self._has_material_conflict = material_conflict self.materialConflictChanged.emit() def setMachineConflict(self, machine_conflict): self._has_machine_conflict = machine_conflict self.machineConflictChanged.emit() def setQualityChangesConflict(self, quality_changes_conflict): self._has_quality_changes_conflict = quality_changes_conflict self.qualityChangesConflictChanged.emit() def getResult(self): if "machine" in self._result and not self._has_machine_conflict: self._result["machine"] = None if "quality_changes" in self._result and not self._has_quality_changes_conflict: self._result["quality_changes"] = None if "material" in self._result and not self._has_material_conflict: self._result["material"] = None return self._result def _createViewFromQML(self): path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("3MFReader"), self._qml_url)) self._component = QQmlComponent(Application.getInstance()._engine, path) self._context = QQmlContext(Application.getInstance()._engine.rootContext()) self._context.setContextProperty("manager", self) self._view = self._component.create(self._context) if self._view is None: Logger.log("c", "QQmlComponent status %s", self._component.status()) Logger.log("c", "QQmlComponent error string %s", self._component.errorString()) def show(self): # Emit signal so the right thread actually shows the view. if threading.current_thread() != threading.main_thread(): self._lock.acquire() # Reset the result self._result = {"machine": self._default_strategy, "quality_changes": self._default_strategy, "material": self._default_strategy} self._visible = True self.showDialogSignal.emit() @pyqtSlot() ## Used to notify the dialog so the lock can be released. def notifyClosed(self): if self._result is None: self._result = {} self._lock.release() def hide(self): self._visible = False self._lock.release() self._view.hide() @pyqtSlot() def onOkButtonClicked(self): self._view.hide() self.hide() @pyqtSlot() def onCancelButtonClicked(self): self._view.hide() self.hide() self._result = {} ## Block thread until the dialog is closed. def waitForClose(self): if self._visible: if threading.current_thread() != threading.main_thread(): self._lock.acquire() self._lock.release() else: # If this is not run from a separate thread, we need to ensure that the events are still processed. while self._visible: time.sleep(1 / 50) QCoreApplication.processEvents() # Ensure that the GUI does not freeze. def __show(self): if self._view is None: self._createViewFromQML() if self._view: self._view.show()
class MachineAction(QObject, PluginObject): def __init__(self, key, label = ""): super().__init__() self._key = key self._label = label self._qml_url = "" self._component = None self._context = None self._view = None self._finished = False labelChanged = pyqtSignal() onFinished = pyqtSignal() def getKey(self): return self._key @pyqtProperty(str, notify = labelChanged) def label(self): return self._label def setLabel(self, label): if self._label != label: self._label = label self.labelChanged.emit() ## Reset the action to it's default state. # This should not be re-implemented by child classes, instead re-implement _reset. # /sa _reset @pyqtSlot() def reset(self): self._finished = False self._reset() ## Protected implementation of reset. # /sa reset() def _reset(self): pass @pyqtSlot() def setFinished(self): self._finished = True self._reset() self.onFinished.emit() @pyqtProperty(bool, notify = onFinished) def finished(self): return self._finished def _createViewFromQML(self): path = QUrl.fromLocalFile( os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), self._qml_url)) self._component = QQmlComponent(Application.getInstance()._engine, path) self._context = QQmlContext(Application.getInstance()._engine.rootContext()) self._context.setContextProperty("manager", self) self._view = self._component.create(self._context) @pyqtProperty(QObject, constant = True) def displayItem(self): if not self._component: self._createViewFromQML() return self._view
class DiscoverUM3Action(MachineAction): def __init__(self): super().__init__("DiscoverUM3Action", catalog.i18nc("@action", "Connect via Network")) self._qml_url = "DiscoverUM3Action.qml" self._network_plugin = None self.__additional_components_context = None self.__additional_component = None self.__additional_components_view = None Application.getInstance().engineCreatedSignal.connect(self._createAdditionalComponentsView) self._last_zeroconf_event_time = time.time() self._zeroconf_change_grace_period = ( 0.25 ) # Time to wait after a zeroconf service change before allowing a zeroconf reset printersChanged = pyqtSignal() @pyqtSlot() def startDiscovery(self): if not self._network_plugin: self._network_plugin = ( Application.getInstance().getOutputDeviceManager().getOutputDevicePlugin("UM3NetworkPrinting") ) self._network_plugin.printerListChanged.connect(self._onPrinterDiscoveryChanged) self.printersChanged.emit() ## Re-filters the list of printers. @pyqtSlot() def reset(self): self.printersChanged.emit() @pyqtSlot() def restartDiscovery(self): # Ensure that there is a bit of time after a printer has been discovered. # This is a work around for an issue with Qt 5.5.1 up to Qt 5.7 which can segfault if we do this too often. # It's most likely that the QML engine is still creating delegates, where the python side already deleted or # garbage collected the data. # Whatever the case, waiting a bit ensures that it doesn't crash. if time.time() - self._last_zeroconf_event_time > self._zeroconf_change_grace_period: if not self._network_plugin: self.startDiscovery() else: self._network_plugin.startDiscovery() @pyqtSlot(str, str) def removeManualPrinter(self, key, address): if not self._network_plugin: return self._network_plugin.removeManualPrinter(key, address) @pyqtSlot(str, str) def setManualPrinter(self, key, address): if key != "": # This manual printer replaces a current manual printer self._network_plugin.removeManualPrinter(key) if address != "": self._network_plugin.addManualPrinter(address) def _onPrinterDiscoveryChanged(self, *args): self._last_zeroconf_event_time = time.time() self.printersChanged.emit() @pyqtProperty("QVariantList", notify=printersChanged) def foundDevices(self): if self._network_plugin: if Application.getInstance().getGlobalContainerStack(): global_printer_type = Application.getInstance().getGlobalContainerStack().getBottom().getId() else: global_printer_type = "unknown" printers = list(self._network_plugin.getPrinters().values()) # TODO; There are still some testing printers that don't have a correct printer type, so don't filter out unkown ones just yet. printers = [ printer for printer in printers if printer.printerType == global_printer_type or printer.printerType == "unknown" ] printers.sort(key=lambda k: k.name) return printers else: return [] @pyqtSlot(str) def setKey(self, key): global_container_stack = Application.getInstance().getGlobalContainerStack() if global_container_stack: meta_data = global_container_stack.getMetaData() if "um_network_key" in meta_data: global_container_stack.setMetaDataEntry("um_network_key", key) # Delete old authentication data. global_container_stack.removeMetaDataEntry("network_authentication_id") global_container_stack.removeMetaDataEntry("network_authentication_key") else: global_container_stack.addMetaDataEntry("um_network_key", key) if self._network_plugin: # Ensure that the connection states are refreshed. self._network_plugin.reCheckConnections() @pyqtSlot(result=str) def getStoredKey(self): global_container_stack = Application.getInstance().getGlobalContainerStack() if global_container_stack: meta_data = global_container_stack.getMetaData() if "um_network_key" in meta_data: return global_container_stack.getMetaDataEntry("um_network_key") return "" @pyqtSlot() def loadConfigurationFromPrinter(self): machine_manager = Application.getInstance().getMachineManager() hotend_ids = machine_manager.printerOutputDevices[0].hotendIds for index in range(len(hotend_ids)): machine_manager.printerOutputDevices[0].hotendIdChanged.emit(index, hotend_ids[index]) material_ids = machine_manager.printerOutputDevices[0].materialIds for index in range(len(material_ids)): machine_manager.printerOutputDevices[0].materialIdChanged.emit(index, material_ids[index]) def _createAdditionalComponentsView(self): Logger.log("d", "Creating additional ui components for UM3.") path = QUrl.fromLocalFile( os.path.join(PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), "UM3InfoComponents.qml") ) self.__additional_component = QQmlComponent(Application.getInstance()._engine, path) # We need access to engine (although technically we can't) self.__additional_components_context = QQmlContext(Application.getInstance()._engine.rootContext()) self.__additional_components_context.setContextProperty("manager", self) self.__additional_components_view = self.__additional_component.create(self.__additional_components_context) if not self.__additional_components_view: Logger.log("w", "Could not create ui components for UM3.") return Application.getInstance().addAdditionalComponent( "monitorButtons", self.__additional_components_view.findChild(QObject, "networkPrinterConnectButton") ) Application.getInstance().addAdditionalComponent( "machinesDetailPane", self.__additional_components_view.findChild(QObject, "networkPrinterConnectionInfo") )
# -*- coding : utf-8 -*- from PyQt5.QtCore import QUrl,QCoreApplication from PyQt5.QtGui import QGuiApplication from PyQt5.QtQml import QQmlEngine,QQmlComponent import os import sys app = QGuiApplication(sys.argv) engine = QQmlEngine() component = QQmlComponent(engine) component.loadUrl(QUrl("main.qml")) top = component.create() if top : top.show() sys.exit(app.exec_())
engine = QQmlEngine(app) #engine = QQmlApplicationEngine() # doesn't quite work because we aren't actually using the component associated # with this engine engine.quit.connect(app.quit) # from http://pyqt.sourceforge.net/Docs/PyQt5/qml.html # Register the Python type. Its URI is 'People', it's v1.0 and the type # will be called 'Person' in QML. qmlRegisterType(Weather, 'WeatherCategory', 1, 0, 'Weather') qmlRegisterType(DataPoint, 'WeatherCategory', 1, 0, 'DataPoint') qmlRegisterType(DataBlock, 'WeatherCategory', 1, 0, 'DataBlock') qmlRegisterType(Geocoder, 'WeatherCategory', 1, 0, 'Geocoder') component = QQmlComponent(engine) component.loadUrl(QUrl('WeatherDash.qml')) # Create the QML user interface. Auto creates its own engine view = QQuickView() engine2 = view.engine # Does not run #engine2.quit.connect(app.quit) #view.setSource(QUrl('PyTest.qml')) # To Satisfy cool-retro-term needs view.rootContext().setContextProperty('devicePixelRatio', app.devicePixelRatio()) view.setSource(QUrl('WeatherDash.qml')) #view.setResizeMode(QDeclarativeView.SizeRootObjectToView)
class PrinterOutputDevice(QObject, OutputDevice): def __init__(self, device_id, parent = None): super().__init__(device_id = device_id, parent = parent) self._container_registry = ContainerRegistry.getInstance() self._target_bed_temperature = 0 self._bed_temperature = 0 self._num_extruders = 1 self._hotend_temperatures = [0] * self._num_extruders self._target_hotend_temperatures = [0] * self._num_extruders self._material_ids = [""] * self._num_extruders self._hotend_ids = [""] * self._num_extruders self._progress = 0 self._head_x = 0 self._head_y = 0 self._head_z = 0 self._connection_state = ConnectionState.closed self._connection_text = "" self._time_elapsed = 0 self._time_total = 0 self._job_state = "" self._job_name = "" self._error_text = "" self._accepts_commands = True self._preheat_bed_timeout = 900 # Default time-out for pre-heating the bed, in seconds. self._preheat_bed_timer = QTimer() # Timer that tracks how long to preheat still. self._preheat_bed_timer.setSingleShot(True) self._preheat_bed_timer.timeout.connect(self.cancelPreheatBed) self._printer_state = "" self._printer_type = "unknown" self._camera_active = False self._monitor_view_qml_path = "" self._monitor_component = None self._monitor_item = None self._qml_context = None def requestWrite(self, nodes, file_name = None, filter_by_machine = False, file_handler = None): raise NotImplementedError("requestWrite needs to be implemented") ## Signals # Signal to be emitted when bed temp is changed bedTemperatureChanged = pyqtSignal() # Signal to be emitted when target bed temp is changed targetBedTemperatureChanged = pyqtSignal() # Signal when the progress is changed (usually when this output device is printing / sending lots of data) progressChanged = pyqtSignal() # Signal to be emitted when hotend temp is changed hotendTemperaturesChanged = pyqtSignal() # Signal to be emitted when target hotend temp is changed targetHotendTemperaturesChanged = pyqtSignal() # Signal to be emitted when head position is changed (x,y,z) headPositionChanged = pyqtSignal() # Signal to be emitted when either of the material ids is changed materialIdChanged = pyqtSignal(int, str, arguments = ["index", "id"]) # Signal to be emitted when either of the hotend ids is changed hotendIdChanged = pyqtSignal(int, str, arguments = ["index", "id"]) # Signal that is emitted every time connection state is changed. # it also sends it's own device_id (for convenience sake) connectionStateChanged = pyqtSignal(str) connectionTextChanged = pyqtSignal() timeElapsedChanged = pyqtSignal() timeTotalChanged = pyqtSignal() jobStateChanged = pyqtSignal() jobNameChanged = pyqtSignal() errorTextChanged = pyqtSignal() acceptsCommandsChanged = pyqtSignal() printerStateChanged = pyqtSignal() printerTypeChanged = pyqtSignal() # Signal to be emitted when some drastic change occurs in the remaining time (not when the time just passes on normally). preheatBedRemainingTimeChanged = pyqtSignal() @pyqtProperty(QObject, constant=True) def monitorItem(self): # Note that we specifically only check if the monitor component is created. # It could be that it failed to actually create the qml item! If we check if the item was created, it will try to # create the item (and fail) every time. if not self._monitor_component: self._createMonitorViewFromQML() return self._monitor_item def _createMonitorViewFromQML(self): path = QUrl.fromLocalFile(self._monitor_view_qml_path) # Because of garbage collection we need to keep this referenced by python. self._monitor_component = QQmlComponent(Application.getInstance()._engine, path) # Check if the context was already requested before (Printer output device might have multiple items in the future) if self._qml_context is None: self._qml_context = QQmlContext(Application.getInstance()._engine.rootContext()) self._qml_context.setContextProperty("OutputDevice", self) self._monitor_item = self._monitor_component.create(self._qml_context) if self._monitor_item is None: Logger.log("e", "QQmlComponent status %s", self._monitor_component.status()) Logger.log("e", "QQmlComponent error string %s", self._monitor_component.errorString()) @pyqtProperty(str, notify=printerTypeChanged) def printerType(self): return self._printer_type @pyqtProperty(str, notify=printerStateChanged) def printerState(self): return self._printer_state @pyqtProperty(str, notify = jobStateChanged) def jobState(self): return self._job_state def _updatePrinterType(self, printer_type): if self._printer_type != printer_type: self._printer_type = printer_type self.printerTypeChanged.emit() def _updatePrinterState(self, printer_state): if self._printer_state != printer_state: self._printer_state = printer_state self.printerStateChanged.emit() def _updateJobState(self, job_state): if self._job_state != job_state: self._job_state = job_state self.jobStateChanged.emit() @pyqtSlot(str) def setJobState(self, job_state): self._setJobState(job_state) def _setJobState(self, job_state): Logger.log("w", "_setJobState is not implemented by this output device") @pyqtSlot() def startCamera(self): self._camera_active = True self._startCamera() def _startCamera(self): Logger.log("w", "_startCamera is not implemented by this output device") @pyqtSlot() def stopCamera(self): self._camera_active = False self._stopCamera() def _stopCamera(self): Logger.log("w", "_stopCamera is not implemented by this output device") @pyqtProperty(str, notify = jobNameChanged) def jobName(self): return self._job_name def setJobName(self, name): if self._job_name != name: self._job_name = name self.jobNameChanged.emit() ## Gives a human-readable address where the device can be found. @pyqtProperty(str, constant = True) def address(self): Logger.log("w", "address is not implemented by this output device.") ## A human-readable name for the device. @pyqtProperty(str, constant = True) def name(self): Logger.log("w", "name is not implemented by this output device.") return "" @pyqtProperty(str, notify = errorTextChanged) def errorText(self): return self._error_text ## Set the error-text that is shown in the print monitor in case of an error def setErrorText(self, error_text): if self._error_text != error_text: self._error_text = error_text self.errorTextChanged.emit() @pyqtProperty(bool, notify = acceptsCommandsChanged) def acceptsCommands(self): return self._accepts_commands ## Set a flag to signal the UI that the printer is not (yet) ready to receive commands def setAcceptsCommands(self, accepts_commands): if self._accepts_commands != accepts_commands: self._accepts_commands = accepts_commands self.acceptsCommandsChanged.emit() ## Get the bed temperature of the bed (if any) # This function is "final" (do not re-implement) # /sa _getBedTemperature implementation function @pyqtProperty(float, notify = bedTemperatureChanged) def bedTemperature(self): return self._bed_temperature ## Set the (target) bed temperature # This function is "final" (do not re-implement) # /param temperature new target temperature of the bed (in deg C) # /sa _setTargetBedTemperature implementation function @pyqtSlot(int) def setTargetBedTemperature(self, temperature): self._setTargetBedTemperature(temperature) if self._target_bed_temperature != temperature: self._target_bed_temperature = temperature self.targetBedTemperatureChanged.emit() ## The total duration of the time-out to pre-heat the bed, in seconds. # # \return The duration of the time-out to pre-heat the bed, in seconds. @pyqtProperty(int, constant = True) def preheatBedTimeout(self): return self._preheat_bed_timeout ## The remaining duration of the pre-heating of the bed. # # This is formatted in M:SS format. # \return The duration of the time-out to pre-heat the bed, formatted. @pyqtProperty(str, notify = preheatBedRemainingTimeChanged) def preheatBedRemainingTime(self): if not self._preheat_bed_timer.isActive(): return "" period = self._preheat_bed_timer.remainingTime() if period <= 0: return "" minutes, period = divmod(period, 60000) #60000 milliseconds in a minute. seconds, _ = divmod(period, 1000) #1000 milliseconds in a second. if minutes <= 0 and seconds <= 0: return "" return "%d:%02d" % (minutes, seconds) ## Time the print has been printing. # Note that timeTotal - timeElapsed should give time remaining. @pyqtProperty(float, notify = timeElapsedChanged) def timeElapsed(self): return self._time_elapsed ## Total time of the print # Note that timeTotal - timeElapsed should give time remaining. @pyqtProperty(float, notify=timeTotalChanged) def timeTotal(self): return self._time_total @pyqtSlot(float) def setTimeTotal(self, new_total): if self._time_total != new_total: self._time_total = new_total self.timeTotalChanged.emit() @pyqtSlot(float) def setTimeElapsed(self, time_elapsed): if self._time_elapsed != time_elapsed: self._time_elapsed = time_elapsed self.timeElapsedChanged.emit() ## Home the head of the connected printer # This function is "final" (do not re-implement) # /sa _homeHead implementation function @pyqtSlot() def homeHead(self): self._homeHead() ## Home the head of the connected printer # This is an implementation function and should be overriden by children. def _homeHead(self): Logger.log("w", "_homeHead is not implemented by this output device") ## Home the bed of the connected printer # This function is "final" (do not re-implement) # /sa _homeBed implementation function @pyqtSlot() def homeBed(self): self._homeBed() ## Home the bed of the connected printer # This is an implementation function and should be overriden by children. # /sa homeBed def _homeBed(self): Logger.log("w", "_homeBed is not implemented by this output device") ## Protected setter for the bed temperature of the connected printer (if any). # /parameter temperature Temperature bed needs to go to (in deg celsius) # /sa setTargetBedTemperature def _setTargetBedTemperature(self, temperature): Logger.log("w", "_setTargetBedTemperature is not implemented by this output device") ## Pre-heats the heated bed of the printer. # # \param temperature The temperature to heat the bed to, in degrees # Celsius. # \param duration How long the bed should stay warm, in seconds. @pyqtSlot(float, float) def preheatBed(self, temperature, duration): Logger.log("w", "preheatBed is not implemented by this output device.") ## Cancels pre-heating the heated bed of the printer. # # If the bed is not pre-heated, nothing happens. @pyqtSlot() def cancelPreheatBed(self): Logger.log("w", "cancelPreheatBed is not implemented by this output device.") ## Protected setter for the current bed temperature. # This simply sets the bed temperature, but ensures that a signal is emitted. # /param temperature temperature of the bed. def _setBedTemperature(self, temperature): if self._bed_temperature != temperature: self._bed_temperature = temperature self.bedTemperatureChanged.emit() ## Get the target bed temperature if connected printer (if any) @pyqtProperty(int, notify = targetBedTemperatureChanged) def targetBedTemperature(self): return self._target_bed_temperature ## Set the (target) hotend temperature # This function is "final" (do not re-implement) # /param index the index of the hotend that needs to change temperature # /param temperature The temperature it needs to change to (in deg celsius). # /sa _setTargetHotendTemperature implementation function @pyqtSlot(int, int) def setTargetHotendTemperature(self, index, temperature): self._setTargetHotendTemperature(index, temperature) if self._target_hotend_temperatures[index] != temperature: self._target_hotend_temperatures[index] = temperature self.targetHotendTemperaturesChanged.emit() ## Implementation function of setTargetHotendTemperature. # /param index Index of the hotend to set the temperature of # /param temperature Temperature to set the hotend to (in deg C) # /sa setTargetHotendTemperature def _setTargetHotendTemperature(self, index, temperature): Logger.log("w", "_setTargetHotendTemperature is not implemented by this output device") @pyqtProperty("QVariantList", notify = targetHotendTemperaturesChanged) def targetHotendTemperatures(self): return self._target_hotend_temperatures @pyqtProperty("QVariantList", notify = hotendTemperaturesChanged) def hotendTemperatures(self): return self._hotend_temperatures ## Protected setter for the current hotend temperature. # This simply sets the hotend temperature, but ensures that a signal is emitted. # /param index Index of the hotend # /param temperature temperature of the hotend (in deg C) def _setHotendTemperature(self, index, temperature): if self._hotend_temperatures[index] != temperature: self._hotend_temperatures[index] = temperature self.hotendTemperaturesChanged.emit() @pyqtProperty("QVariantList", notify = materialIdChanged) def materialIds(self): return self._material_ids @pyqtProperty("QVariantList", notify = materialIdChanged) def materialNames(self): result = [] for material_id in self._material_ids: if material_id is None: result.append(i18n_catalog.i18nc("@item:material", "No material loaded")) continue containers = self._container_registry.findInstanceContainers(type = "material", GUID = material_id) if containers: result.append(containers[0].getName()) else: result.append(i18n_catalog.i18nc("@item:material", "Unknown material")) return result ## List of the colours of the currently loaded materials. # # The list is in order of extruders. If there is no material in an # extruder, the colour is shown as transparent. # # The colours are returned in hex-format AARRGGBB or RRGGBB # (e.g. #800000ff for transparent blue or #00ff00 for pure green). @pyqtProperty("QVariantList", notify = materialIdChanged) def materialColors(self): result = [] for material_id in self._material_ids: if material_id is None: result.append("#00000000") #No material. continue containers = self._container_registry.findInstanceContainers(type = "material", GUID = material_id) if containers: result.append(containers[0].getMetaDataEntry("color_code")) else: result.append("#00000000") #Unknown material. return result ## Protected setter for the current material id. # /param index Index of the extruder # /param material_id id of the material def _setMaterialId(self, index, material_id): if material_id and material_id != "" and material_id != self._material_ids[index]: Logger.log("d", "Setting material id of hotend %d to %s" % (index, material_id)) self._material_ids[index] = material_id self.materialIdChanged.emit(index, material_id) @pyqtProperty("QVariantList", notify = hotendIdChanged) def hotendIds(self): return self._hotend_ids ## Protected setter for the current hotend id. # /param index Index of the extruder # /param hotend_id id of the hotend def _setHotendId(self, index, hotend_id): if hotend_id and hotend_id != self._hotend_ids[index]: Logger.log("d", "Setting hotend id of hotend %d to %s" % (index, hotend_id)) self._hotend_ids[index] = hotend_id self.hotendIdChanged.emit(index, hotend_id) elif not hotend_id: Logger.log("d", "Removing hotend id of hotend %d.", index) self._hotend_ids[index] = None self.hotendIdChanged.emit(index, None) ## Let the user decide if the hotends and/or material should be synced with the printer # NB: the UX needs to be implemented by the plugin def materialHotendChangedMessage(self, callback): Logger.log("w", "materialHotendChangedMessage needs to be implemented, returning 'Yes'") callback(QMessageBox.Yes) ## Attempt to establish connection def connect(self): raise NotImplementedError("connect needs to be implemented") ## Attempt to close the connection def close(self): raise NotImplementedError("close needs to be implemented") @pyqtProperty(bool, notify = connectionStateChanged) def connectionState(self): return self._connection_state ## Set the connection state of this output device. # /param connection_state ConnectionState enum. def setConnectionState(self, connection_state): if self._connection_state != connection_state: self._connection_state = connection_state self.connectionStateChanged.emit(self._id) @pyqtProperty(str, notify = connectionTextChanged) def connectionText(self): return self._connection_text ## Set a text that is shown on top of the print monitor tab def setConnectionText(self, connection_text): if self._connection_text != connection_text: self._connection_text = connection_text self.connectionTextChanged.emit() ## Ensure that close gets called when object is destroyed def __del__(self): self.close() ## Get the x position of the head. # This function is "final" (do not re-implement) @pyqtProperty(float, notify = headPositionChanged) def headX(self): return self._head_x ## Get the y position of the head. # This function is "final" (do not re-implement) @pyqtProperty(float, notify = headPositionChanged) def headY(self): return self._head_y ## Get the z position of the head. # In some machines it's actually the bed that moves. For convenience sake we simply see it all as head movements. # This function is "final" (do not re-implement) @pyqtProperty(float, notify = headPositionChanged) def headZ(self): return self._head_z ## Update the saved position of the head # This function should be called when a new position for the head is received. def _updateHeadPosition(self, x, y ,z): position_changed = False if self._head_x != x: self._head_x = x position_changed = True if self._head_y != y: self._head_y = y position_changed = True if self._head_z != z: self._head_z = z position_changed = True if position_changed: self.headPositionChanged.emit() ## Set the position of the head. # In some machines it's actually the bed that moves. For convenience sake we simply see it all as head movements. # This function is "final" (do not re-implement) # /param x new x location of the head. # /param y new y location of the head. # /param z new z location of the head. # /param speed Speed by which it needs to move (in mm/minute) # /sa _setHeadPosition implementation function @pyqtSlot("long", "long", "long") @pyqtSlot("long", "long", "long", "long") def setHeadPosition(self, x, y, z, speed = 3000): self._setHeadPosition(x, y , z, speed) ## Set the X position of the head. # This function is "final" (do not re-implement) # /param x x position head needs to move to. # /param speed Speed by which it needs to move (in mm/minute) # /sa _setHeadx implementation function @pyqtSlot("long") @pyqtSlot("long", "long") def setHeadX(self, x, speed = 3000): self._setHeadX(x, speed) ## Set the Y position of the head. # This function is "final" (do not re-implement) # /param y y position head needs to move to. # /param speed Speed by which it needs to move (in mm/minute) # /sa _setHeadY implementation function @pyqtSlot("long") @pyqtSlot("long", "long") def setHeadY(self, y, speed = 3000): self._setHeadY(y, speed) ## Set the Z position of the head. # In some machines it's actually the bed that moves. For convenience sake we simply see it all as head movements. # This function is "final" (do not re-implement) # /param z z position head needs to move to. # /param speed Speed by which it needs to move (in mm/minute) # /sa _setHeadZ implementation function @pyqtSlot("long") @pyqtSlot("long", "long") def setHeadZ(self, z, speed = 3000): self._setHeadY(z, speed) ## Move the head of the printer. # Note that this is a relative move. If you want to move the head to a specific position you can use # setHeadPosition # This function is "final" (do not re-implement) # /param x distance in x to move # /param y distance in y to move # /param z distance in z to move # /param speed Speed by which it needs to move (in mm/minute) # /sa _moveHead implementation function @pyqtSlot("long", "long", "long") @pyqtSlot("long", "long", "long", "long") def moveHead(self, x = 0, y = 0, z = 0, speed = 3000): self._moveHead(x, y, z, speed) ## Implementation function of moveHead. # /param x distance in x to move # /param y distance in y to move # /param z distance in z to move # /param speed Speed by which it needs to move (in mm/minute) # /sa moveHead def _moveHead(self, x, y, z, speed): Logger.log("w", "_moveHead is not implemented by this output device") ## Implementation function of setHeadPosition. # /param x new x location of the head. # /param y new y location of the head. # /param z new z location of the head. # /param speed Speed by which it needs to move (in mm/minute) # /sa setHeadPosition def _setHeadPosition(self, x, y, z, speed): Logger.log("w", "_setHeadPosition is not implemented by this output device") ## Implementation function of setHeadX. # /param x new x location of the head. # /param speed Speed by which it needs to move (in mm/minute) # /sa setHeadX def _setHeadX(self, x, speed): Logger.log("w", "_setHeadX is not implemented by this output device") ## Implementation function of setHeadY. # /param y new y location of the head. # /param speed Speed by which it needs to move (in mm/minute) # /sa _setHeadY def _setHeadY(self, y, speed): Logger.log("w", "_setHeadY is not implemented by this output device") ## Implementation function of setHeadZ. # /param z new z location of the head. # /param speed Speed by which it needs to move (in mm/minute) # /sa _setHeadZ def _setHeadZ(self, z, speed): Logger.log("w", "_setHeadZ is not implemented by this output device") ## Get the progress of any currently active process. # This function is "final" (do not re-implement) # /sa _getProgress # /returns float progress of the process. -1 indicates that there is no process. @pyqtProperty(float, notify = progressChanged) def progress(self): return self._progress ## Set the progress of any currently active process # /param progress Progress of the process. def setProgress(self, progress): if self._progress != progress: self._progress = progress self.progressChanged.emit()
class MachineAction(QObject, PluginObject): ## Create a new Machine action. # \param key unique key of the machine action # \param label Human readable label used to identify the machine action. def __init__(self, key, label = ""): super().__init__() self._key = key self._label = label self._qml_url = "" self._component = None self._context = None self._view = None self._finished = False labelChanged = pyqtSignal() onFinished = pyqtSignal() def getKey(self): return self._key @pyqtProperty(str, notify = labelChanged) def label(self): return self._label def setLabel(self, label): if self._label != label: self._label = label self.labelChanged.emit() ## Reset the action to it's default state. # This should not be re-implemented by child classes, instead re-implement _reset. # /sa _reset @pyqtSlot() def reset(self): self._component = None self._finished = False self._reset() ## Protected implementation of reset. # /sa reset() def _reset(self): pass @pyqtSlot() def setFinished(self): self._finished = True self._reset() self.onFinished.emit() @pyqtProperty(bool, notify = onFinished) def finished(self): return self._finished ## Protected helper to create a view object based on provided QML. def _createViewFromQML(self): path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), self._qml_url)) self._component = QQmlComponent(Application.getInstance()._engine, path) self._context = QQmlContext(Application.getInstance()._engine.rootContext()) self._context.setContextProperty("manager", self) self._view = self._component.create(self._context) if self._view is None: Logger.log("c", "QQmlComponent status %s", self._component.status()) Logger.log("c", "QQmlComponent error string %s", self._component.errorString()) @pyqtProperty(QObject, constant = True) def displayItem(self): if not self._component: self._createViewFromQML() return self._view
from PyQt5.QtQml import QQmlComponent, QQmlApplicationEngine from PyQt5.QtQuick import QQuickWindow from view_model import ViewModel if __name__ == '__main__': myApp = QApplication(sys.argv) engine = QQmlApplicationEngine() context = engine.rootContext() engine.addImportPath("/home/bob/Qt/5.11.2/Automotive/sources/qtapplicationmanager/dummyimports/") # create a view model view_model = ViewModel() # bind the view model to the context context.setContextProperty('view_model', view_model) component = QQmlComponent(engine) component.loadUrl(QUrl('mainwindow.qml')) # some boilerplate to make sure the component is ready before showing if component.status() != QQmlComponent.Ready: if component.status() == QQmlComponent.Error: sys.exit(component.errorString()) root_window: QQuickWindow = component.create() myApp.exec_() sys.exit()