def create_qquick_view(script_root, qml_dirs=[], img_providers=[]): view = QQuickView() add_import_paths(view.engine(), qml_dirs) add_image_providers(view.engine(), img_providers) view.setResizeMode(QQuickView.SizeRootObjectToView) view.setSource(QUrl.fromLocalFile(script_root)) return view
def main(): global app # sys.argv.extend(['-platform', 'eglfs']) # Qt Charts uses Qt Graphics View Framework for drawing, therefore QApplication must be used. app = QApplication(sys.argv) viewer = QQuickView() # The following are needed to make examples run without having to install the module # in desktop environments. extraImportPath = QGuiApplication.applicationDirPath() if sys.platform == 'win32': extraImportPath += "/../../../../qml" else: extraImportPath += "/../../../qml" viewer.engine().addImportPath(extraImportPath) viewer.engine().quit.connect(app.quit) viewer.setTitle("QML Oscilloscope") dataSource = datasource.DataSource(viewer) viewer.rootContext().setContextProperty("dataSource", dataSource) main_qml = path.dirname(__file__) + "/qml/qmloscilloscope/main.qml" viewer.setSource(QUrl(main_qml)) viewer.setResizeMode(QQuickView.SizeRootObjectToView) viewer.setColor(QColor("#404040")) viewer.show() return app.exec_()
def main(): argv = sys.argv app = QGuiApplication(argv) qmlRegisterType(FigureCanvasQTAggToolbar, "Backend", 1, 0, "FigureToolbar") imgProvider = MatplotlibIconProvider() view = QQuickView() view.engine().addImageProvider("mplIcons", imgProvider) view.setResizeMode(QQuickView.SizeRootObjectToView) view.setSource( QUrl( os.path.join(os.path.dirname(__file__), 'backend_qtquick5', 'FigureToolbar.qml'))) win = view.rootObject() fig = win.findChild(QObject, "figure").getFigure() ax = fig.add_subplot(111) x = np.linspace(-5, 5) ax.plot(x, np.sin(x)) view.show() rc = app.exec_() # There is some trouble arising when deleting all the objects here # but I have not figure out how to solve the error message. # It looks like 'app' is destroyed before some QObject sys.exit(rc)
def qt_t1(): app = QGuiApplication([]) view = QQuickView() path = './qml/side3/side3.qml' # 加载的QML文件 view.engine().quit.connect(app.quit) view.setSource(QUrl(path)) view.show() root = view.rootObject() root.updateRotater() # 调用QML函数 app.exec_()
def add_qml_import_path(self, view: QQuickView) -> None: """ Manually set the path to the QML folder to fix errors with unicode paths. This is needed only on Windows when packaged with Nuitka. """ if Options.freezer != "nuitka": return qml_dir = Options.res_dir.parent / "PyQt5" / "Qt" / "qml" log.debug(f"Setting QML import path for {view} to {qml_dir!r}") view.engine().addImportPath(str(qml_dir))
def main(): # Create main app myApp = QGuiApplication(sys.argv) # myApp.setWindowIcon(QIcon('./images/icon.png')) # Create a View and set its properties appView = QQuickView() appView.setMinimumHeight(640) appView.setMinimumWidth(1024) appView.setTitle('Authorize Kerberos') engine = appView.engine() engine.quit.connect(myApp.quit) context = engine.rootContext() # add paths appDir = 'file:///' + QDir.currentPath() context.setContextProperty('appDir', appDir) # add controllers mainController = MainController() context.setContextProperty('PyConsole', mainController) context.setContextProperty('mainController', mainController) # Show the View appView.setSource(QUrl('./qml/main.qml')) appView.showMaximized() # Execute the Application and Exit myApp.exec_() sys.exit()
class TabletShortcuts(QGuiApplication): def __init__(self, argv): QGuiApplication.__init__(self, argv) self.view = QQuickView() self.bus = QDBusConnection.sessionBus() self.server = MyDBUSServer(self) self.bus.registerObject("/app", self.server) self.bus.registerService("sevanteri.TabletShortcuts") self.view.setTitle("TabletShortcuts") self.view.setResizeMode(QQuickView.SizeRootObjectToView) self.view.setSource(QUrl('main.qml')) self.root = self.view.rootObject() self.showView() self.root.runCommand.connect(self.run) self.root.hideView.connect(self.view.hide) self.view.engine().quit.connect(self.quit) def run(self, cmd): return Popen(shlex.split(cmd)) def quit(self): self.exit() def showView(self): if self.view.isVisible(): self.view.hide() else: # width, height = TabletShortcuts.getScreenGeometry() # self.view.setGeometry(1, 1, width, height) self.view.show() def getScreenGeometry(): output = Popen("xrandr | grep 'current'", shell=True, stdout=PIPE)\ .communicate()[0].decode('UTF-8') m = re.search('current.([0-9]+).x.([0-9]+)', output) width = int(m.group(1)) height = int(m.group(2)) return (width, height)
def main(): import sys QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling) QCoreApplication.setOrganizationName("QtExamples") app = QGuiApplication(sys.argv) view = QQuickView() view.engine().quit.connect(app.quit) view.setSource(QUrl("qrc:/demos/clocks/clocks.qml")) if view.status() == QQuickView.Error: sys.exit(-1) view.setResizeMode(QQuickView.SizeRootObjectToView) view.show() sys.exit(app.exec_())
def main(): app = QApplication(sys.argv) # Register the Python type. # qmlRegisterType(Hal.Component, 'Hal', 1, 0, 'Component') # qmlRegisterType(Hal.Pin, 'Hal', 1, 0, 'Pin') qmlRegisterType(Stat.Stat, 'LinuxCNC', 1, 0, 'Stat') qmlRegisterType(Axis.Axis, 'LinuxCNC', 1, 0, 'Axis') qmlRegisterType(Command.Command, 'LinuxCNC', 1, 0, 'Command') qmlRegisterType(ErrorChannel.ErrorChannel, 'LinuxCNC', 1, 0, 'ErrorChannel') quickview = QQuickView() quickview.setSource(QUrl('gui/qml/main.qml')) quickview.showFullScreen() quickview.engine().quit.connect(app.quit) app.exec_()
def main(): app = QGuiApplication(sys.argv) view = QQuickView() schema = [ "pyLabel", "pyColor", ] model = Model(schema) items = [{ "pyLabel": "First Item", "pyColor": "white", }, { "pyLabel": "Second Item", "pyColor": "white", }] for item in items: model.append(item) engine = view.engine() context = engine.rootContext() context.setContextProperty("pyModel", model) view.setSource(QUrl("app.qml")) view.setResizeMode(view.SizeRootObjectToView) view.show() # Appending to the model QTimer.singleShot( 2000, lambda: model.append({ "pyLabel": "Third Item", "pyColor": "steelblue" })) # Modifying an item in the model QTimer.singleShot( 3000, lambda: model.setData( model.createIndex(1, 0), # 1th item, 0th column "New pLabel!", schema.index("pyLabel"), )) app.exec_()
def setupUi(self, Notification): msgv = QQuickView() msgv.setSource(QUrl('message.qml')) rootObj = msgv.rootObject() total_width = int(QQmlProperty.read(rootObj, "width")) total_height = int(QQmlProperty.read(rootObj, "height")) self.twidth = total_width self.theight = total_height qmlengine = msgv.engine() qmlengine.addImageProvider("bicimage", BicImageProvider()) rootObj.findChild(QObject, "img").setProperty( "source", "image://bicimage/" + Notification.mssg["icon"]) rootObj.findChild(QObject, "textprocess").setProperty( "text", Notification.mssg["process"]) rootObj.findChild(QObject, "filename").setProperty("text", Notification.mssg["file"]) rootObj.findChild(QObject, "textaction").setProperty( "text", Notification.mssg["action"]) rootObj.findChild(QObject, "textaction").setProperty("color", Notification.mssg["color"]) rootObj.findChild(QObject, "timestr").setProperty("text", Notification.mssg["time"]) Notification.setObjectName(_fromUtf8("Notification")) Notification.setMinimumSize(QtCore.QSize(total_width, total_height)) Notification.setMaximumSize(QtCore.QSize(total_width, total_height)) # Notification.setWindowOpacity(1.0) # Notification.setAutoFillBackground(False) # Notification.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) centralwidget = QWidget.createWindowContainer(msgv) centralwidget.setObjectName(_fromUtf8("centralwidget")) Notification.setCentralWidget(centralwidget)
def main(): app = QGuiApplication(sys.argv) app.setApplicationName('InfiniteCopy') openDataBase() view = QQuickView() clipboardItemModel = ClipboardItemModel() clipboardItemModel.create() filterProxyModel = QSortFilterProxyModel() filterProxyModel.setSourceModel(clipboardItemModel) clipboard = Clipboard() clipboard.setFormats([ mimeText, mimeHtml, mimePng, mimeSvg ]) clipboard.changed.connect(clipboardItemModel.addItem) engine = view.engine() imageProvider = ClipboardItemModelImageProvider(clipboardItemModel) engine.addImageProvider("items", imageProvider) context = view.rootContext() context.setContextProperty('clipboardItemModel', clipboardItemModel) context.setContextProperty('clipboardItemModelFilterProxy', filterProxyModel) context.setContextProperty('clipboard', clipboard) view.setSource(QUrl.fromLocalFile('qml/MainWindow.qml')) view.setGeometry(100, 100, 400, 240) view.show() engine.quit.connect(QGuiApplication.quit) return app.exec_()
def QmlWidget(qmlpath: str, context: dict, parent: QWidget) -> QWidget: """ Generate a QtWidgets widget from a QML file. :qmlpath The pat of the QML file. :context The context objects to expose to QML. """ qmlpath = os.fspath(qmlpath) view = QQuickView() engine = view.engine() for name, obj in context.items(): engine.rootContext().setContextProperty(name, obj) container = QWidget.createWindowContainer(view, parent) container.setStyleSheet("Widget { padding: 7px; }") view.setSource(QUrl.fromLocalFile(qmlpath)) return container
class P2CQMLApplication(QGuiApplication): def __init__(self, list_of_str): super().__init__(list_of_str) self._current_category = None self._current_torrent = None self._current_torrent_info = None self._status_timer = QTimer(self) self._movies_thread = None self._search_thread = None def run_view(self): self._view = QQuickView() self._view.engine().addImportPath("qml") self._rctx = self._view.rootContext() self._view.setResizeMode(QQuickView.SizeRootObjectToView) # set context variables self.categories = [] self._rctx.setContextProperty("categoriesModel", self.categories) self.tiles = [] self.torrents = [] self._rctx.setContextProperty("moviesModel", self.tiles) self._set_loading(False) self._view.setSource(QUrl('qrc:/qml.qml')) self._view.showFullScreen() # self._view.show() def connect_daemon(self, daemon: P2CDaemon): self._daemon = daemon self._set_categories() self._connect_signals() def play(self, movie: Movie): self._set_movie_status("Ready to play!") self._set_media(movie) self._daemon.play(movie) self._set_additional_media_info() def buffer(self, movie: Movie): seconds = self._current_torrent.get_seconds_to_buffer() info = "just started" if seconds: if seconds < 15: info = "just a moment" else: # rount to minutes minutes = int(seconds / 60) + 1 if minutes == 1: info = "1 minute" else: info = "{} minutes".format(minutes) self._set_movie_status("Buffering... ({})".format(info)) self._daemon.buffer(movie) self._set_additional_media_info() def wait_for_metadata(self): self._set_movie_status("Getting metadata...") if self._current_torrent: self._set_additional_media_info(self._current_torrent.name) def select_movie(self, torrent: Torrent) -> Movie: movies = torrent.get_movies() if len(movies) == 0: return # TODO: show dialog with movie selecting instead of doing it automatically return max(movies, key=lambda x: x.size) def update_status(self): torrent = self._current_torrent if torrent: if (torrent.has_torrent_info()): movie = self.select_movie(torrent) if not movie: self._set_movie_status( "No movie in this torrent. Please, select another.") return torrent.download_file(movie.path) self._set_duration(movie) if not self._daemon.is_playing(movie): if (movie.can_play()): # print(movie.get_subtitles()) self.play(movie) else: self.buffer(movie) ### DEBUG INFO text = "s: %s, num p: %s, rate: %s kbs, p_rate: %s kbs" % ( torrent.get_status()['state'], torrent.get_status()['num_peers'], int(torrent.get_status()['download_rate'] / 1024), int(torrent.get_status()['download_payload_rate'] / 1024), ) self._view.rootObject().setProperty("debugText", text) ### END DEBUG INFO else: self.wait_for_metadata() else: self.wait_for_metadata() def on_category_clicked(self, index): # clear list self._set_torrents([], loading=True) category = self._daemon.get_categories()[index] self._current_category = category if self._current_category: self._search_thread = None self._movies_thread = SetMoviesThread(self._current_category) self._movies_thread.start() self._movies_thread.got_movies.connect(self._threaded_set_torrents) def on_movie_clicked(self, index): self._view.rootObject().setProperty("isMovieScene", True) torrent_ui = self.torrents[index] self._current_torrent = self._daemon.get_torrent(torrent_ui) self._current_torrent_info = torrent_ui self.update_status() def on_search(self, query): if len(query) < 3: return # clear list self._set_torrents([], loading=True) self._movies_thread = None self._search_thread = SearchThread(query, self._daemon.search) self._search_thread.start() self._search_thread.got_movies.connect(self._threaded_set_torrents) def on_exit(self): self.quit() def _connect_signals(self): self._view.rootObject().categoryClicked.connect( self.on_category_clicked) self._view.rootObject().movieClicked.connect(self.on_movie_clicked) self._view.rootObject().movieClicked.connect(self.on_movie_clicked) self._view.rootObject().searchQuery.connect(self.on_search) self._view.rootObject().exitAction.connect(self.on_exit) self._status_timer.timeout.connect(self.update_status) self._status_timer.start(500) def _set_movie_status(self, text): self._rctx.setContextProperty("movieStatus", text) def _set_media(self, movie: Movie): file_name = movie.get_target_path() self._rctx.setContextProperty("movieSource", QUrl.fromLocalFile(file_name)) def _set_additional_media_info(self, title=None): self._rctx.setContextProperty( "title", title or self._current_torrent_info.title or self._current_torrent_info.label) self._rctx.setContextProperty( "poster", self._current_torrent_info.poster if self._current_torrent_info and self._current_torrent_info.poster else '') def _set_categories(self): data = [] for category in self._daemon.get_categories(): data.append(Tile(category.label, category.service.name)) self._rctx.setContextProperty("categoriesModel", data) self.categories = data def _threaded_set_torrents(self, data, thread): # if latest action if thread == self._movies_thread or thread == self._search_thread: self._set_torrents(data) def _set_torrents(self, data, loading=False): # only existing tiles for (tile, torrent_info) in zip(self.tiles, data[:len(self.tiles)]): if torrent_info.title: tile.name = torrent_info.title tile.source = torrent_info.label else: tile.name = torrent_info.label tile.source = None tile.poster = torrent_info.poster tile.description = torrent_info.description if len(data) != len(self.tiles): for torrent_info in data[len(self.tiles):]: if torrent_info.title: tile = Tile(torrent_info.title, torrent_info.label, torrent_info.poster, torrent_info.description) else: tile = Tile(torrent_info.label, None, torrent_info.poster, torrent_info.description) self.tiles.append(tile) self._rctx.setContextProperty("moviesModel", self.tiles) self.torrents = data self._set_loading(loading) def _set_loading(self, loading): self._rctx.setContextProperty("loadingMask", loading) def _set_duration(self, movie: Movie): tdelta = movie.get_movie_duration() if tdelta: self._view.rootObject().setProperty("movieDuration", tdelta.seconds * 1000)
#import components_rc #pyrcc5 -o qml_rc.py qml.qrc #import qml_rc if __name__ == '__main__': os.environ['QT_QUICK_CONTROLS_CONF'] = '/etc/qml4cop/qtquickcontrols2.conf' os.environ['XDG_CONFIG_HOME'] = '/etc' os.environ['QT_IM_MODULE'] = 'qtvirtualkeyboard' app_path = os.path.abspath(os.path.dirname(sys.argv[0])) sys.path.insert( 1, os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'Components')) app = QApplication(sys.argv) app.setOrganizationDomain("qml4cop") app.setOrganizationName("qml4cop") app.setApplicationName("qml4cop") app.setApplicationVersion("0.62.0") quickview = QQuickView() quickview.setSource(QUrl('MainPage.qml')) quickview.engine().quit.connect(app.quit) quickview.show() sys.exit(app.exec_())
class USBPrinterManager(QObject, SignalEmitter, Extension): def __init__(self, parent = None): super().__init__(parent) self._serial_port_list = [] self._printer_connections = [] self._check_ports_thread = threading.Thread(target = self._updateConnectionList) self._check_ports_thread.daemon = True self._check_ports_thread.start() self._progress = 0 self._control_view = None self._firmware_view = None self._extruder_temp = 0 self._bed_temp = 0 self._error_message = "" ## Add menu item to top menu of the application. self.setMenuName("Firmware") self.addMenuItem(i18n_catalog.i18n("Update Firmware"), self.updateAllFirmware) pyqtError = pyqtSignal(str, arguments = ["amount"]) processingProgress = pyqtSignal(float, arguments = ["amount"]) pyqtExtruderTemperature = pyqtSignal(float, arguments = ["amount"]) pyqtBedTemperature = pyqtSignal(float, arguments = ["amount"]) ## Show firmware interface. # This will create the view if its not already created. def spawnFirmwareInterface(self, serial_port): if self._firmware_view is None: self._firmware_view = QQuickView() self._firmware_view.engine().rootContext().setContextProperty("manager",self) self._firmware_view.setSource(QUrl("plugins/USBPrinting/FirmwareUpdateWindow.qml")) self._firmware_view.show() ## Show control interface. # This will create the view if its not already created. def spawnControlInterface(self,serial_port): if self._control_view is None: self._control_view = QQuickView() self._control_view.engine().rootContext().setContextProperty("manager",self) self._control_view.setSource(QUrl("plugins/USBPrinting/ControlWindow.qml")) self._control_view.show() @pyqtProperty(float,notify = processingProgress) def progress(self): return self._progress @pyqtProperty(float,notify = pyqtExtruderTemperature) def extruderTemperature(self): return self._extruder_temp @pyqtProperty(float,notify = pyqtBedTemperature) def bedTemperature(self): return self._bed_temp @pyqtProperty(str,notify = pyqtError) def error(self): return self._error_message ## Check all serial ports and create a PrinterConnection object for them. # Note that this does not validate if the serial ports are actually usable! # This (the validation) is only done when the connect function is called. def _updateConnectionList(self): while True: temp_serial_port_list = self.getSerialPortList(only_list_usb = True) if temp_serial_port_list != self._serial_port_list: # Something changed about the list since we last changed something. disconnected_ports = [port for port in self._serial_port_list if port not in temp_serial_port_list ] self._serial_port_list = temp_serial_port_list for serial_port in self._serial_port_list: if self.getConnectionByPort(serial_port) is None: # If it doesn't already exist, add it if not os.path.islink(serial_port): # Only add the connection if it's a non symbolic link connection = PrinterConnection.PrinterConnection(serial_port) connection.connect() connection.connectionStateChanged.connect(self.serialConectionStateCallback) connection.progressChanged.connect(self.onProgress) connection.onExtruderTemperatureChange.connect(self.onExtruderTemperature) connection.onBedTemperatureChange.connect(self.onBedTemperature) connection.onError.connect(self.onError) self._printer_connections.append(connection) for serial_port in disconnected_ports: # Close connections and remove them from list. connection = self.getConnectionByPort(serial_port) if connection != None: self._printer_connections.remove(connection) connection.close() time.sleep(5) # Throttle, as we don"t need this information to be updated every single second. def updateAllFirmware(self): self.spawnFirmwareInterface("") for printer_connection in self._printer_connections: printer_connection.updateFirmware(Resources.getPath(Resources.FirmwareLocation, self._getDefaultFirmwareName())) def updateFirmwareBySerial(self, serial_port): printer_connection = self.getConnectionByPort(serial_port) if printer_connection is not None: self.spawnFirmwareInterface(printer_connection.getSerialPort()) printer_connection.updateFirmware(Resources.getPath(Resources.FirmwareLocation, self._getDefaultFirmwareName())) def _getDefaultFirmwareName(self): machine_type = Application.getInstance().getActiveMachine().getTypeID() firmware_name = "" baudrate = 250000 if sys.platform.startswith("linux"): baudrate = 115200 if machine_type == "ultimaker_original": firmware_name = "MarlinUltimaker" firmware_name += "-%d" % (baudrate) elif machine_type == "ultimaker_original_plus": firmware_name = "MarlinUltimaker-UMOP-%d" % (baudrate) elif machine_type == "Witbox": return "MarlinWitbox.hex" elif machine_type == "ultimaker2go": return "MarlinUltimaker2go.hex" elif machine_type == "ultimaker2extended": return "MarlinUltimaker2extended.hex" elif machine_type == "ultimaker2": return "MarlinUltimaker2.hex" ##TODO: Add check for multiple extruders if firmware_name != "": firmware_name += ".hex" return firmware_name ## Callback for extruder temperature change def onExtruderTemperature(self, serial_port, index, temperature): self._extruder_temp = temperature self.pyqtExtruderTemperature.emit(temperature) ## Callback for bed temperature change def onBedTemperature(self, serial_port,temperature): self._bed_temperature = temperature self.pyqtBedTemperature.emit(temperature) ## Callback for error def onError(self, error): self._error_message = error self.pyqtError.emit(error) ## Callback for progress change def onProgress(self, progress, serial_port): self._progress = progress self.processingProgress.emit(progress) ## Attempt to connect with all possible connections. def connectAllConnections(self): for connection in self._printer_connections: connection.connect() ## Send gcode to printer and start printing def sendGCodeByPort(self, serial_port, gcode_list): printer_connection = self.getConnectionByPort(serial_port) if printer_connection is not None: printer_connection.printGCode(gcode_list) return True return False @pyqtSlot() def cancelPrint(self): for printer_connection in self.getActiveConnections(): printer_connection.cancelPrint() ## Send gcode to all active printers. # \return True if there was at least one active connection. def sendGCodeToAllActive(self, gcode_list): for printer_connection in self.getActiveConnections(): printer_connection.printGCode(gcode_list) if len(self.getActiveConnections()): return True else: return False ## Send a command to a printer indentified by port # \param serial port String indentifieing the port # \param command String with the g-code command to send. # \return True if connection was found, false otherwise def sendCommandByPort(self, serial_port, command): printer_connection = self.getConnectionByPort(serial_port) if printer_connection is not None: printer_connection.sendCommand(command) return True return False ## Send a command to all active (eg; connected) printers # \param command String with the g-code command to send. # \return True if at least one connection was found, false otherwise def sendCommandToAllActive(self, command): for printer_connection in self.getActiveConnections(): printer_connection.sendCommand(command) if len(self.getActiveConnections()): return True else: return False ## Callback if the connection state of a connection is changed. # This adds or removes the connection as a possible output device. def serialConectionStateCallback(self, serial_port): connection = self.getConnectionByPort(serial_port) if connection.isConnected(): Application.getInstance().addOutputDevice(serial_port, { "id": serial_port, "function": self.spawnControlInterface, "description": "Write to USB {0}".format(serial_port), "icon": "print_usb", "priority": 1 }) else: Application.getInstance().removeOutputDevice(serial_port) @pyqtSlot() def startPrint(self): gcode_list = getattr(Application.getInstance().getController().getScene(), "gcode_list", None) if gcode_list: final_list = [] for gcode in gcode_list: final_list += gcode.split("\n") self.sendGCodeToAllActive(gcode_list) ## Get a list of printer connection objects that are connected. def getActiveConnections(self): return [connection for connection in self._printer_connections if connection.isConnected()] ## Get a printer connection object by serial port def getConnectionByPort(self, serial_port): for printer_connection in self._printer_connections: if serial_port == printer_connection.getSerialPort(): return printer_connection return None ## Create a list of serial ports on the system. # \param only_list_usb If true, only usb ports are listed def getSerialPortList(self,only_list_usb=False): base_list = [] if platform.system() == "Windows": import winreg try: key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,"HARDWARE\\DEVICEMAP\\SERIALCOMM") i = 0 while True: values = winreg.EnumValue(key, i) if not base_list or "USBSER" in values[0]: base_list += [values[1]] i += 1 except Exception as e: pass if base_list: base_list = base_list + glob.glob("/dev/ttyUSB*") + glob.glob("/dev/ttyACM*") + glob.glob("/dev/cu.usb*") base_list = filter(lambda s: "Bluetooth" not in s, base_list) # Filter because mac sometimes puts them in the list else: base_list = base_list + glob.glob("/dev/ttyUSB*") + glob.glob("/dev/ttyACM*") + glob.glob("/dev/cu.*") + glob.glob("/dev/tty.usb*") + glob.glob("/dev/rfcomm*") + glob.glob("/dev/serial/by-id/*") return base_list
class P2CQMLApplication(QGuiApplication): def __init__(self, list_of_str): super().__init__(list_of_str) self._current_category = None self._current_torrent = None self._current_torrent_info = None self._status_timer = QTimer(self) self._movies_thread = None self._search_thread = None def run_view(self): self._view = QQuickView() self._view.engine().addImportPath("qml") self._rctx = self._view.rootContext() self._view.setResizeMode(QQuickView.SizeRootObjectToView) # set context variables self.categories = [] self._rctx.setContextProperty("categoriesModel", self.categories) self.tiles = [] self.torrents = [] self._rctx.setContextProperty("moviesModel", self.tiles) self._set_loading(False) self._view.setSource(QUrl('qrc:/qml.qml')) self._view.showFullScreen() # self._view.show() def connect_daemon(self, daemon: P2CDaemon): self._daemon = daemon self._set_categories() self._connect_signals() def play(self, movie: Movie): self._set_movie_status("Ready to play!") self._set_media(movie) self._daemon.play(movie) self._set_additional_media_info() def buffer(self, movie: Movie): seconds = self._current_torrent.get_seconds_to_buffer() info = "just started" if seconds: if seconds < 15: info = "just a moment" else: # rount to minutes minutes = int(seconds / 60) + 1 if minutes == 1: info = "1 minute" else: info = "{} minutes".format(minutes) self._set_movie_status("Buffering... ({})".format(info)) self._daemon.buffer(movie) self._set_additional_media_info() def wait_for_metadata(self): self._set_movie_status("Getting metadata...") if self._current_torrent: self._set_additional_media_info(self._current_torrent.name) def select_movie(self, torrent: Torrent) -> Movie: movies = torrent.get_movies() if len(movies) == 0: return # TODO: show dialog with movie selecting instead of doing it automatically return max(movies, key=lambda x: x.size) def update_status(self): torrent = self._current_torrent if torrent: if(torrent.has_torrent_info()): movie = self.select_movie(torrent) if not movie: self._set_movie_status("No movie in this torrent. Please, select another.") return torrent.download_file(movie.path) self._set_duration(movie) if not self._daemon.is_playing(movie): if(movie.can_play()): # print(movie.get_subtitles()) self.play(movie) else: self.buffer(movie) ### DEBUG INFO text = "s: %s, num p: %s, rate: %s kbs, p_rate: %s kbs" % ( torrent.get_status()['state'], torrent.get_status()['num_peers'], int(torrent.get_status()['download_rate'] / 1024), int(torrent.get_status()['download_payload_rate'] / 1024), ) self._view.rootObject().setProperty("debugText", text) ### END DEBUG INFO else: self.wait_for_metadata() else: self.wait_for_metadata() def on_category_clicked(self, index): # clear list self._set_torrents([], loading=True) category = self._daemon.get_categories()[index] self._current_category = category if self._current_category: self._search_thread = None self._movies_thread = SetMoviesThread(self._current_category) self._movies_thread.start() self._movies_thread.got_movies.connect(self._threaded_set_torrents) def on_movie_clicked(self, index): self._view.rootObject().setProperty("isMovieScene", True) torrent_ui = self.torrents[index] self._current_torrent = self._daemon.get_torrent(torrent_ui) self._current_torrent_info = torrent_ui self.update_status() def on_search(self, query): if len(query) < 3: return # clear list self._set_torrents([], loading=True) self._movies_thread = None self._search_thread = SearchThread(query, self._daemon.search) self._search_thread.start() self._search_thread.got_movies.connect(self._threaded_set_torrents) def on_exit(self): self.quit() def _connect_signals(self): self._view.rootObject().categoryClicked.connect( self.on_category_clicked) self._view.rootObject().movieClicked.connect(self.on_movie_clicked) self._view.rootObject().movieClicked.connect(self.on_movie_clicked) self._view.rootObject().searchQuery.connect(self.on_search) self._view.rootObject().exitAction.connect(self.on_exit) self._status_timer.timeout.connect(self.update_status) self._status_timer.start(500) def _set_movie_status(self, text): self._rctx.setContextProperty("movieStatus", text) def _set_media(self, movie: Movie): file_name = movie.get_target_path() self._rctx.setContextProperty("movieSource", QUrl.fromLocalFile(file_name)) def _set_additional_media_info(self, title=None): self._rctx.setContextProperty("title", title or self._current_torrent_info.title or self._current_torrent_info.label) self._rctx.setContextProperty("poster", self._current_torrent_info.poster if self._current_torrent_info and self._current_torrent_info.poster else '') def _set_categories(self): data = [] for category in self._daemon.get_categories(): data.append(Tile(category.label, category.service.name)) self._rctx.setContextProperty("categoriesModel", data) self.categories = data def _threaded_set_torrents(self, data, thread): # if latest action if thread == self._movies_thread or thread == self._search_thread: self._set_torrents(data) def _set_torrents(self, data, loading=False): # only existing tiles for (tile, torrent_info) in zip(self.tiles, data[:len(self.tiles)]): if torrent_info.title: tile.name = torrent_info.title tile.source = torrent_info.label else: tile.name = torrent_info.label tile.source = None tile.poster = torrent_info.poster tile.description = torrent_info.description if len(data) != len(self.tiles): for torrent_info in data[len(self.tiles):]: if torrent_info.title: tile = Tile(torrent_info.title, torrent_info.label, torrent_info.poster, torrent_info.description) else: tile = Tile(torrent_info.label, None, torrent_info.poster, torrent_info.description) self.tiles.append(tile) self._rctx.setContextProperty("moviesModel", self.tiles) self.torrents = data self._set_loading(loading) def _set_loading(self, loading): self._rctx.setContextProperty("loadingMask", loading) def _set_duration(self, movie:Movie): tdelta = movie.get_movie_duration() if tdelta: self._view.rootObject().setProperty("movieDuration", tdelta.seconds * 1000)
class Selector(QWidget): def __init__(self, goal_context, config_path, experimentlogger): self.path = config_path super(Selector, self).__init__() self.ros_timer = QTimer() self.ros_timer.timeout.connect(self.ros_poller) self.setup_ui() self.AUTOEXECUTE = False self.ignore_move_events = False self.context = goal_context self.planner = None self.current_plan = None self.current_action_succeeded = False self.current_action_index = 0 self.current_menu_index = 0 self.task = None self.planner = planning.Planner(goal_context.init, self.path) self.ros_handler = None self.experiment_logger = experimentlogger self.init_menu() self.show_goal_ui() def ros_poller(self): # print "checking for ROS triggered changes in ROS event queue" if self.ros_handler and self.ros_handler.event_queue: # print "Processing events from ROS event queue. There are %d events" % len(self.ros_handler.event_queue) event = self.ros_handler.event_queue.pop(0) # print "popped ", str(event[0]) if "teleop" not in str(event[0]): event[0]( *event[1] ) # event is a pair (method,[params]) the asteriks unpacks parameters else: logger.debug( "HEY, don't teleoperate while actions are running: %s", str(event[0])) # print "executed ", str(event[0]) def setup_ui(self): self.view = QQuickView() self.view.setResizeMode(QQuickView.SizeRootObjectToView) container = QWidget.createWindowContainer(self.view) container.setFocusPolicy(Qt.StrongFocus) layout = QVBoxLayout() layout.addWidget(container) self.setLayout(layout) ctx = self.view.rootContext() ctx.setContextProperty("selector", self) ctx.setContextProperty("C", ui_constants) self.set_menu([]) self.set_plan([]) self.set_current(None) self.view.setSource(QUrl(self.path + 'ui.qml')) self.resize(800, 800) self.move(300, 300) self.setWindowTitle('Goal Planner GUI') self.setWindowIcon(QIcon('images/icon.png')) reload = QShortcut(QKeySequence("Ctrl+R"), self) reload.activated.connect(self.reload_ui) quit = QShortcut(QKeySequence("Ctrl+C"), self) quit.activated.connect(self.quit) quit = QShortcut(QKeySequence("Esc"), self) quit.activated.connect(self.quit) self.ros_timer.start(10) self.showMaximized() def test_populate(self): l = ["give", "grasp", "drop", "open", "close"] self.set_menu(l) def set_current(self, goal): ctx = self.view.rootContext() ctx.setContextProperty("currentGoal", QVariant(goal)) self.current = goal # do not free the list while it's in the model def set_menu(self, elems): ctx = self.view.rootContext() ctx.setContextProperty("selectionsModel", QVariant(elems)) self.elems = elems # do not free the list while it's in the model def set_plan(self, elems): ctx = self.view.rootContext() ctx.setContextProperty("planModel", QVariant(elems)) self.plans = elems # do not free the list while it's in the model def activate_loading(self): compute_image_focus = self.view.rootObject().findChild( QObject, "compute_image_focus") compute_image_focus.turnOn() def deactivate_loading(self): compute_image_focus = self.view.rootObject().findChild( QObject, "compute_image_focus") compute_image_focus.turnOff() @pyqtSlot() def goal_menu(self): class create_goal_menu(QThread): def __init__(self, instance): QThread.__init__(self) self.instance = instance def __del__(self): self.wait() def run(self): if constants.SHOW_FUNCTION_GOALS: self.instance.next_goals = goals.FunctionGoal.initial_goals( self.instance.context ) + goals.ActionGoal.initial_goals(self.instance.context) else: self.instance.next_goals = goals.ActionGoal.initial_goals( self.instance.context) # logger2.debug("Next goals: %s", map(str, self.next_goals)) self.instance.next_goals = [ g for g in self.instance.next_goals if self.instance.filter_goal(g) ] """ Shows the selection of options """ self.experiment_logger.log_performance( "Goal Menu shows next goals ...") self.create_goal_menu_thread = create_goal_menu(self) self.create_goal_menu_thread.finished.connect( self.create_goal_menu_done) self.create_goal_menu_thread.start() self.activate_loading() def create_goal_menu_done(self): items = [GoalMenuItem(g, -1) for g in self.next_goals] items.append(BackMenuItem()) self.current_goal = GOAL_MENU self.build_header(None) self.set_menu(items) self.experiment_logger.log_performance( "Goal Menu shows next goals done", True) self.create_goal_menu_thread = None self.deactivate_loading() @pyqtSlot() def action_menu(self): self.next_goals = goals.ExecActionGoal.initial_goals(self.context) items = [GoalMenuItem(g, -1) for g in self.next_goals] items.append(BackMenuItem()) self.current_goal = ACTION_MENU self.build_header(None) self.set_menu(items) @pyqtSlot(int) def select_goal(self, index): # logger2.debug("select goal") # image = self.view.rootObject().findChild(QObject, "compute_image") # image.turnOn() # self.experiment_logger.log_performance("user chose goal #%s" %index) #traceback.print_stack() if self.next_goals: self.display_goal(self.next_goals[index]) #self.experiment_logger.log_performance("goal #%s displayed" %index) # image.turnOff() @pyqtSlot(int) def select_action(self, index): if self.ignore_move_events: logger.debug( "aborting action execution because an action is already in progress" ) return #print self.current_action_index, index if not (self.current_action_index == index or self.current_action_index + 1 == index): logger.debug("Execute previous actions first!!!") return if self.current_plan and index < len(self.current_plan): if self.current_plan[ index].status == plans.ActionStatusEnum.EXECUTED: logger.debug("The action was already executed") return plan_node = self.current_plan[index] plan_node.status = plans.ActionStatusEnum.IN_PROGRESS self.display_status_text("Action is in progress") self.ignore_move_events = True self.ros_handler.execute_on_robot(plan_node.action, plan_node.arguments) items = [ PlanItem(pnode, self.context) for pnode in self.current_plan ] self.set_plan(items) planView = self.view.rootObject().findChild(QObject, "planView") planView.setProperty("currentIndex", index) self.current_action_index = index self.current_action_succeeded = False logger.debug("action selection of %s done, action executed" % index) # self.show_plan_ui() def action_executed(self): success = self.current_action_succeeded planView = self.view.rootObject().findChild(QObject, "planView") index = self.current_action_index logger.debug("current action index %d was executed. success = %s" % (index, success)) if success: plan_node = self.current_plan[index] if not self.planner.execute_action(plan_node.action, plan_node.arguments): plan_node.status = plans.ActionStatusEnum.FAILED logger.fatal( "\033[91mWarning warning warning, Planner found action to be infeasible... aborting\033[0m" ) #assert False self.current_plan[index].status = plans.ActionStatusEnum.EXECUTED #logger.debug("will refresh context now") #self.refresh_context(self.planner.problem) else: self.current_plan[ index].status = plans.ActionStatusEnum.UNSUCCESSFUL self.ignore_move_events = False logger.debug("select next action in plan GUI") planView = self.view.rootObject().findChild(QObject, "planView") items = [PlanItem(pnode, self.context) for pnode in self.current_plan] self.set_plan(items) if success and index + 1 < len(self.current_plan): planView.setProperty("currentIndex", index + 1) # select next plan step if self.AUTOEXECUTE: logger.debug("Auto-executing next") pui = self.view.rootObject().findChild(QObject, "planner_ui") pui.teleop_select() else: logger.debug("autoexecute ist turned off") self.refresh_context(self.planner.problem) else: planView.setProperty("currentIndex", index) # self.show_plan_ui() def handle_world_update(self): world = self.view.rootObject().findChild(QObject, "world_image") world.turn_world() self.init_menu() self.show_goal_ui() self.planner.set_state(self.context.init) # print("World change happened, world turning image displayed. Now I check the plan") # print("goal= ",self.goal) # self.plan(goal) @pyqtSlot() def back(self): if self.ignore_move_events and self.current_plan[ self. current_action_index].status == plans.ActionStatusEnum.IN_PROGRESS: #action is currently running -> abort it self.current_plan[ self. current_action_index].status = plans.ActionStatusEnum.UNSUCCESSFUL planView = self.view.rootObject().findChild(QObject, "planView") items = [ PlanItem(pnode, self.context) for pnode in self.current_plan ] self.set_plan(items) planView.setProperty("currentIndex", self.current_action_index) self.ros_handler.abort_current_action() self.ignore_move_events = False return if self.menu_stack: g = self.menu_stack.pop() self.current_goal = None if g == GOAL_MENU: self.goal_menu() elif g == ACTION_MENU: self.action_menu() else: self.display_goal(g) else: self.init_menu() self.show_goal_ui() @pyqtSlot() def choose(self): logger.debug("choose pressed") # self.menu_stack.pop() goal = self.current_goal if goal.is_unique(): if isinstance(goal, goals.ExecActionGoal): self.execute_action_goal(goal) else: self.plan(goal) return if self.current_goal is not None: self.menu_stack.append(self.current_goal) current_index = goal.arg_index(goal.get_current_arg()) logger.debug("index = %d", current_index) logger.debug( "\033[93m next from current goal----------\n----------\n--------\n-------" ) self.next_goals = [ g for g in self.current_goal.next_all() if not g.is_empty() and self.filter_goal(g) ] #self.next_goals = [g for g in self.current_goal.next() if not g.is_empty() and self.filter_goal(g)] logger.debug("\033[0m next_goals: %s", map(str, self.next_goals)) items = [GoalMenuItem(g, current_index) for g in self.next_goals] if self.menu_stack: items.append(ChooseMenuItem()) items.append(BackMenuItem()) self.build_header(goal) self.set_menu(items) def reload_ui(self): # print "reload_ui clear cache" self.view.engine().clearComponentCache() # print "reload_ui set menu" self.set_menu([]) # print "reload_ui set plan" self.set_plan([]) # print "reload_ui set current" self.set_current(None) if self.mode == MENU_MODE_GOAL: logger.debug("reload_ui show goal") self.show_goal_ui() else: logger.debug("reload_ui show plan") self.show_plan_ui() #print "reload_ui updatself.menu_stack.append(self.current_goal)e" self.repaint() @pyqtSlot() def quit(self): #pass # self.hide() sys.exit(0) # @pyqtSlot('QString') def display_status_text(self, displaytext): # print "about to display in statusbar >%s<" % displaytext bar = self.view.rootObject().findChild(QObject, "statusbar") # QMetaObject.invokeMethod(bar, "display", Qt.DirectConnection, Q_ARG(QVariant, displaytext)) #bar.display("%s" % displaytext) bar.display("") def action_help(self, action): help = "" if action == "go": help = "go [robot] [room], i.e., move the robot into a room" elif action == "approach": help = "approach [robot] [target base], i.e., move the robot to a target (furniture, flowerbed, humans) in the current room" elif action == "drop": help = "drop [robot] [object] [target], i.e., drop an object on a target (furniture, flowerbed, humans)" elif action == "arrange": help = "arrange [robot] [flower] [vase], i.e., arrange a flower in a vase" elif action == "open": help = "open [robot] [bottle], i.e., lets the robot open a bottle" elif action == "drink": help = "drink [human] [vessel] [content], i.e., the robot gives a drink in a vessel with the specified content to the human" elif action == "pour": help = "pour [from vessel] [to vessel] [content], i.e., the robot pours a liquid (3. parameter) from the first vessel into the second one" elif action == "give": help = "give [robot] [object] [human], i.e., the robot brings an object to the human" elif action == "grasp": help = "grasp [robot] [object], i.e., the robot grasps an object" elif action == "pick": help = "pick [robot] [flower] [vase], i.e., the robot picks a flower from a vase" else: help = "Unknown action " + action return help @pyqtSlot(int) def display_status(self, index): text = "Unknown Element with Index " + str(index) # print "Displaying ", text # print "Current goal -> ", self.current_goal # print "Current menustack -> ", self.menu_stack # print "current -> ", self.current # print "Mode -> ", self.mode self.current_menu_index = index if self.mode == MENU_MODE_GOAL: if self.current_goal: # print "ui.py/display_status debug dump of current goal:" # print self.current_goal.__class__ # if type(self.current_goal) is not int: # print "active = %s" % self.current_goal.arg_index # print "goal args= " # for arg in self.current_goal.args: # print str(arg) if (index < len(self.next_goals)): next_goal = self.next_goals[index] text = str(next_goal) if isinstance(next_goal, goals.ActionGoal): action = next_goal.action.name help = self.action_help(action) text = "Current: " + text + "\nHelp: " + help elif (index == len(self.next_goals)): text = "BACK" else: text = rootMenu[index].arg[0].text else: if index < len(self.current_plan): text = str(self.current_plan[index]) else: text = "Cannot display status of step %s in a plan of length %s" % ( index, len(self.current_plan)) # if self.current_goal and isinstance(self.current_goal, goals.ActionGoal): # action = self.current_goal.action.name # help = self.action_help(action) # text = "Current: " + text + "\nHelp: " + help self.display_status_text(text) self.experiment_logger.log_navigation(index, text) def init_menu(self): # logger2.debug("initializing menu") # image = self.view.rootObject().findChild(QObject, "compute_image") # image.turnOn() self.mode = MENU_MODE_GOAL self.menu_stack = [] self.current_goal = None self.build_header(None) ctx = self.view.rootContext() # root = self.view.rootObject().findChild(QObject, "rootMenu") logger.debug("set context property to root menu %s", rootMenu) # image.turnOff() ctx.setContextProperty("selectionsModel", rootMenu) self.set_menu(rootMenu) def show_goal_ui(self): self.mode = MENU_MODE_GOAL gui = self.view.rootObject().findChild(QObject, "goal_ui") pui = self.view.rootObject().findChild(QObject, "planner_ui") pui.setProperty("visible", False) gui.setProperty("visible", True) gui.setProperty("focus", True) def show_plan_ui(self): logger.debug("show plan ui in mode %s", self.mode) self.mode = MENU_MODE_PLAN gui = self.view.rootObject().findChild(QObject, "goal_ui") pui = self.view.rootObject().findChild(QObject, "planner_ui") gui.setProperty("visible", False) pui.setProperty("visible", True) pui.setProperty("focus", True) self.display_status(0) def add_image_provider(self, image_provider): self.image_provider = image_provider self.view.rootContext().engine().addImageProvider( 'ros_image_provider', self.image_provider) image_provider.connect_gui(self) # def change_focuspoint_color_srv(self): # widget = self.view.rootObject().findChild(QObject, 'crosshair') # def switch_to_video_view(self): # self.view.rootObject().switch_to_video_view() # def switch_to_main_view(self): # self.view.rootObject().switch_to_main_view() def build_header(self, goal): if goal is None or goal.__class__ == goals.GoalSpec: self.set_current(None) return self.set_current(CurrentGoalItem(goal)) def display_goal(self, goal): class display_goal_menu(QThread): def __init__(self, instance, goal): QThread.__init__(self) self.instance = instance self.goal = goal def __del__(self): self.wait() def run(self): if self.goal.is_unique(): if isinstance(self.goal, goals.ExecActionGoal): self.instance.execute_action_goal(self.goal) else: self.instance.plan(self.goal, False) self.instance.show_plan_flag = True return self.instance.current_index = self.goal.arg_index( self.goal.get_current_arg()) self.instance.next_goals = [ g for g in self.instance.current_goal.next_flattened() if not g.is_empty() and self.instance.filter_goal(g) ] logger.debug("will display goal %s", str(goal)) self.experiment_logger.log_performance("ui.show_goal_ui display goal") # #CalledGoals.Instance().call_goal(goal) # if goal.is_unique(): # if isinstance(goal, goals.ExecActionGoal): # self.execute_action_goal(goal) # else: # self.plan(goal) # return # # if self.current_goal is not None: # self.menu_stack.append(self.current_goal) # # self.current_goal = goal # self.current_index = goal.arg_index(goal.get_current_arg()) #tmp_goals = [(-CalledGoals.Instance().get_calls(g)*100+i, g) for i, g in enumerate(self.current_goal.next_flattened()) if not g.is_empty() and self.filter_goal(g)] #tmp_goals.sort() #self.next_goals = [g for _, g in tmp_goals] if self.current_goal is not None: self.menu_stack.append(self.current_goal) self.current_goal = goal self.show_plan_flag = False self.display_goal_menu_thread = display_goal_menu(self, goal) self.display_goal_menu_thread.finished.connect( self.display_goal_menu_done) self.display_goal_menu_thread.start() self.activate_loading() # self.next_goals = [g for g in self.current_goal.next_flattened() if not g.is_empty() and self.filter_goal(g)] def display_goal_menu_done(self): if self.show_plan_flag: self.plan_update_gui() if self.experiment_logger.autoperform: self.quit() items = [GoalMenuItem(g, self.current_index) for g in self.next_goals] if self.menu_stack: #items.append(ChooseMenuItem()) items.append(BackMenuItem()) self.build_header(self.current_goal) self.set_menu(items) self.experiment_logger.log_performance("ui.display_goal_menu_done", True) self.display_goal_menu_thread = None self.deactivate_loading() def execute_action_goal(self, action_goal): action = action_goal.action problem = self.context.problem #instantiate an action that matches the selected action and execute it valid_args = action_goal.get_matches() action_args = [] for aarg in action_goal.action.args: if aarg in action_goal.used_arguments: i = action_goal.used_arguments.index(aarg) objects = set(tup[i] for tup in valid_args) # print self.args[i], map(str, objects) else: objects = list(problem.get_all_objects(aarg.type)) action_args.append(objects) inst_function = action.get_inst_func(self.context.init) args = None for mapping in action.smart_instantiate(inst_function, action.args, action_args, problem): args = [mapping[a] for a in action.args] break self.planner.execute_action(action, args) #self.refresh_context(self.planner.problem) self.menu_stack = [] self.action_menu() def refresh_context(self, problem, refs=None): if refs is None: # use old references instead refs = self.context.refs self.context = goals.GoalContext(problem, refs) def plan_update_gui(self): items = [PlanItem(pnode, self.context) for pnode in self.current_plan] self.set_plan(items) self.show_plan_ui() def plan(self, goal, update_gui=True): self.menu_stack = [] self.current_goal = None self.current_action_index = 0 assert self.planner is not None self.planner.find_plan(goal) self.current_plan = self.planner.get_plan() if update_gui: self.plan_update_gui() def filter_goal(self, goal): if goal.is_universal(): return False return True
class PreviewTab(QWidget): """Preview of QML component given by 'source' argument. If any file in the source's directory or one of its subdirectories is changed, the view is updated unless paused. Potential errors in the QML code are displayed in red.""" def __init__(self, source=None, parent=None, import_paths=None): super().__init__(parent=parent) self.updating_paused = False self.qml_view = QQuickView() engine = self.qml_view.engine() import_paths = import_paths or [] for import_path in import_paths: engine.addImportPath(import_path) # idea from # https://www.ics.com/blog/combining-qt-widgets-and-qml-qwidgetcreatewindowcontainer self.container = QWidget.createWindowContainer(self.qml_view, self) self.error_info = QLabel() self.error_info.setWordWrap(True) self.qml_source = QUrl() if source is None else QUrl(source) self.update_source() self.pause_button = QPushButton("Pause") self.pause_button.setCheckable(True) layout = QVBoxLayout() layout.setAlignment(Qt.AlignCenter) layout.addWidget(self.error_info) layout.addWidget(self.container) layout.addWidget(self.pause_button) self.setLayout(layout) # Observations using the QFileSystemWatcher in various settings: # A) fileChanged signal and qml file paths # Collected all *.qml files in the directory of the source and all # subdirectories and added to the watcher. Now the first change would # trigger the signal but none of the following # B) additionally connecting directoryChanged signal # same issue # C) both signals, (sub)directory file paths # Collected all subdirectories of the source directory and added it to # the watcher, along with the source directory itself. Works as # expected # D) directoryChanged signal, (sub)directory file paths # same as C) without fileChanged signal, works as expected # Eventual solution: D # This implementation also helped me: # https://github.com/penk/qml-livereload/blob/master/main.cpp self.watcher = QFileSystemWatcher() source_dir = os.path.dirname(source) source_paths = glob.glob(os.path.join(source_dir, "*/"), recursive=True) source_paths.append(source_dir) failed_paths = self.watcher.addPaths(source_paths) if failed_paths: print("Failed to watch paths: {}".format(", ".join(failed_paths))) self.pause_button.clicked.connect(self.toggle_updating) self.qml_view.statusChanged.connect(self.check_status) self.watcher.directoryChanged.connect(self.update_source) def toggle_updating(self, clicked): """Callback for pause button.""" self.pause_button.setText("Resume" if clicked else "Pause") self.updating_paused = clicked # Update when resuming in case of the source having changed if not self.updating_paused: self.update_source() def update_source(self, _=None): """Method and callback to update the QML view source. The second argument is required to have a slot matching the directoryChanged() interface. This immediately returns if updating is paused. """ if self.updating_paused: return # idea from # https://stackoverflow.com/questions/17337493/how-to-reload-qml-file-to-qquickview self.qml_view.setSource(QUrl()) self.qml_view.engine().clearComponentCache() # avoid error: No such file or directory QThread.msleep(50) self.qml_view.setSource(self.qml_source) self.container.setMinimumSize(self.qml_view.size()) self.container.setMaximumSize(self.qml_view.size()) # avoid error label making the window too wide self.error_info.setMaximumWidth(self.container.maximumWidth()) def check_status(self, status): if status == QQuickView.Error: self.error_info.setText("<font color='red'>{}</font>".format( self.qml_view.errors()[-1].toString())) else: self.error_info.clear() def shutdown(self): """Shutdown tab to prepare for removal. Manually delete QML related members to free resources. Otherwise error messages are printed even after closing the tab, indicating that the QML engine still runs in the background. """ del self.container del self.qml_view
class USBPrinterManager(QObject, SignalEmitter, Extension): def __init__(self, parent=None): super().__init__(parent) self._serial_port_list = [] self._printer_connections = [] self._check_ports_thread = threading.Thread( target=self._updateConnectionList) self._check_ports_thread.daemon = True self._check_ports_thread.start() self._progress = 0 self._control_view = None self._firmware_view = None self._extruder_temp = 0 self._bed_temp = 0 self._error_message = "" ## Add menu item to top menu of the application. self.setMenuName("Firmware") self.addMenuItem(i18n_catalog.i18n("Update Firmware"), self.updateAllFirmware) pyqtError = pyqtSignal(str, arguments=["amount"]) processingProgress = pyqtSignal(float, arguments=["amount"]) pyqtExtruderTemperature = pyqtSignal(float, arguments=["amount"]) pyqtBedTemperature = pyqtSignal(float, arguments=["amount"]) ## Show firmware interface. # This will create the view if its not already created. def spawnFirmwareInterface(self, serial_port): if self._firmware_view is None: self._firmware_view = QQuickView() self._firmware_view.engine().rootContext().setContextProperty( "manager", self) self._firmware_view.setSource( QUrl("plugins/USBPrinting/FirmwareUpdateWindow.qml")) self._firmware_view.show() ## Show control interface. # This will create the view if its not already created. def spawnControlInterface(self, serial_port): if self._control_view is None: self._control_view = QQuickView() self._control_view.engine().rootContext().setContextProperty( "manager", self) self._control_view.setSource( QUrl("plugins/USBPrinting/ControlWindow.qml")) self._control_view.show() @pyqtProperty(float, notify=processingProgress) def progress(self): return self._progress @pyqtProperty(float, notify=pyqtExtruderTemperature) def extruderTemperature(self): return self._extruder_temp @pyqtProperty(float, notify=pyqtBedTemperature) def bedTemperature(self): return self._bed_temp @pyqtProperty(str, notify=pyqtError) def error(self): return self._error_message ## Check all serial ports and create a PrinterConnection object for them. # Note that this does not validate if the serial ports are actually usable! # This (the validation) is only done when the connect function is called. def _updateConnectionList(self): while True: temp_serial_port_list = self.getSerialPortList(only_list_usb=True) if temp_serial_port_list != self._serial_port_list: # Something changed about the list since we last changed something. disconnected_ports = [ port for port in self._serial_port_list if port not in temp_serial_port_list ] self._serial_port_list = temp_serial_port_list for serial_port in self._serial_port_list: if self.getConnectionByPort( serial_port ) is None: # If it doesn't already exist, add it if not os.path.islink( serial_port ): # Only add the connection if it's a non symbolic link connection = PrinterConnection.PrinterConnection( serial_port) connection.connect() connection.connectionStateChanged.connect( self.serialConectionStateCallback) connection.progressChanged.connect(self.onProgress) connection.onExtruderTemperatureChange.connect( self.onExtruderTemperature) connection.onBedTemperatureChange.connect( self.onBedTemperature) connection.onError.connect(self.onError) self._printer_connections.append(connection) for serial_port in disconnected_ports: # Close connections and remove them from list. connection = self.getConnectionByPort(serial_port) if connection != None: self._printer_connections.remove(connection) connection.close() time.sleep( 5 ) # Throttle, as we don"t need this information to be updated every single second. def updateAllFirmware(self): self.spawnFirmwareInterface("") for printer_connection in self._printer_connections: printer_connection.updateFirmware( Resources.getPath(Resources.FirmwareLocation, self._getDefaultFirmwareName())) def updateFirmwareBySerial(self, serial_port): printer_connection = self.getConnectionByPort(serial_port) if printer_connection is not None: self.spawnFirmwareInterface(printer_connection.getSerialPort()) printer_connection.updateFirmware( Resources.getPath(Resources.FirmwareLocation, self._getDefaultFirmwareName())) def _getDefaultFirmwareName(self): machine_type = Application.getInstance().getActiveMachine().getTypeID() firmware_name = "" baudrate = 250000 if sys.platform.startswith("linux"): baudrate = 115200 if machine_type == "ultimaker_original": firmware_name = "MarlinUltimaker" firmware_name += "-%d" % (baudrate) elif machine_type == "ultimaker_original_plus": firmware_name = "MarlinUltimaker-UMOP-%d" % (baudrate) elif machine_type == "Witbox": return "MarlinWitbox.hex" elif machine_type == "ultimaker2go": return "MarlinUltimaker2go.hex" elif machine_type == "ultimaker2extended": return "MarlinUltimaker2extended.hex" elif machine_type == "ultimaker2": return "MarlinUltimaker2.hex" ##TODO: Add check for multiple extruders if firmware_name != "": firmware_name += ".hex" return firmware_name ## Callback for extruder temperature change def onExtruderTemperature(self, serial_port, index, temperature): self._extruder_temp = temperature self.pyqtExtruderTemperature.emit(temperature) ## Callback for bed temperature change def onBedTemperature(self, serial_port, temperature): self._bed_temperature = temperature self.pyqtBedTemperature.emit(temperature) ## Callback for error def onError(self, error): self._error_message = error self.pyqtError.emit(error) ## Callback for progress change def onProgress(self, progress, serial_port): self._progress = progress self.processingProgress.emit(progress) ## Attempt to connect with all possible connections. def connectAllConnections(self): for connection in self._printer_connections: connection.connect() ## Send gcode to printer and start printing def sendGCodeByPort(self, serial_port, gcode_list): printer_connection = self.getConnectionByPort(serial_port) if printer_connection is not None: printer_connection.printGCode(gcode_list) return True return False @pyqtSlot() def cancelPrint(self): for printer_connection in self.getActiveConnections(): printer_connection.cancelPrint() ## Send gcode to all active printers. # \return True if there was at least one active connection. def sendGCodeToAllActive(self, gcode_list): for printer_connection in self.getActiveConnections(): printer_connection.printGCode(gcode_list) if len(self.getActiveConnections()): return True else: return False ## Send a command to a printer indentified by port # \param serial port String indentifieing the port # \param command String with the g-code command to send. # \return True if connection was found, false otherwise def sendCommandByPort(self, serial_port, command): printer_connection = self.getConnectionByPort(serial_port) if printer_connection is not None: printer_connection.sendCommand(command) return True return False ## Send a command to all active (eg; connected) printers # \param command String with the g-code command to send. # \return True if at least one connection was found, false otherwise def sendCommandToAllActive(self, command): for printer_connection in self.getActiveConnections(): printer_connection.sendCommand(command) if len(self.getActiveConnections()): return True else: return False ## Callback if the connection state of a connection is changed. # This adds or removes the connection as a possible output device. def serialConectionStateCallback(self, serial_port): connection = self.getConnectionByPort(serial_port) if connection.isConnected(): Application.getInstance().addOutputDevice( serial_port, { "id": serial_port, "function": self.spawnControlInterface, "description": "Write to USB {0}".format(serial_port), "icon": "print_usb", "priority": 1 }) else: Application.getInstance().removeOutputDevice(serial_port) @pyqtSlot() def startPrint(self): gcode_list = getattr( Application.getInstance().getController().getScene(), "gcode_list", None) if gcode_list: final_list = [] for gcode in gcode_list: final_list += gcode.split("\n") self.sendGCodeToAllActive(gcode_list) ## Get a list of printer connection objects that are connected. def getActiveConnections(self): return [ connection for connection in self._printer_connections if connection.isConnected() ] ## Get a printer connection object by serial port def getConnectionByPort(self, serial_port): for printer_connection in self._printer_connections: if serial_port == printer_connection.getSerialPort(): return printer_connection return None ## Create a list of serial ports on the system. # \param only_list_usb If true, only usb ports are listed def getSerialPortList(self, only_list_usb=False): base_list = [] if platform.system() == "Windows": import winreg try: key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM") i = 0 while True: values = winreg.EnumValue(key, i) if not base_list or "USBSER" in values[0]: base_list += [values[1]] i += 1 except Exception as e: pass if base_list: base_list = base_list + glob.glob("/dev/ttyUSB*") + glob.glob( "/dev/ttyACM*") + glob.glob("/dev/cu.usb*") base_list = filter( lambda s: "Bluetooth" not in s, base_list ) # Filter because mac sometimes puts them in the list else: base_list = base_list + glob.glob("/dev/ttyUSB*") + glob.glob( "/dev/ttyACM*") + glob.glob("/dev/cu.*") + glob.glob( "/dev/tty.usb*") + glob.glob("/dev/rfcomm*") + glob.glob( "/dev/serial/by-id/*") return base_list
def sniff_data(qroot): cap = pyshark.FileCapture('D:\\4.pcapng') for p in cap: if 'MODBUS' in p: if p['IP'].src == '192.168.0.103': packet_windturbine_1(p, qroot) else: continue if __name__ == '__main__': path = 'main.qml' app = QGuiApplication([]) view = QQuickView() view.engine().quit.connect(app.quit) view.setSource(QUrl(path)) view.show() context = view.rootContext() rootobj = view.rootObject() sniff_thread = Thread(target=sniff_data, args=(rootobj,)) sniff_thread.setDaemon(True) sniff_thread.start() app.exec_()
class PhotoBoothGUI(QObject): def run(self): # Create main app self.myApp = QApplication(sys.argv) # Create a label and set its properties self.appLabel = QQuickView() #self.appLabel.setSource(QUrl('loading.qml')) # Show the Label self.appLabel.show() # Initialize PhotoBoothEngine. self.pbengine = PhotoBoothEngine() self.pbengine.on_change_url.connect(self.update_url_signal) self.pbengine.on_connect_signal.connect(self.connect_signal) self.pbengine.change_qml(0) self.pbengine.connect_state(0) print("UPDATE") #self.pbengine.on_status.connect(self.appLabel.rootObject().status) #self.pbengine.on_update_filter_preview.connect(self.appLabel.rootObject().updateImageFilterPreview) self.appLabel.rootContext().setContextProperty('pbengine', self.pbengine) self.setup_text_status_fly_component() self.pbengine.start_state_thread(0) # Execute the Application and Exit self.myApp.exec_() sys.exit() def setup_text_status_fly_component(self): # Create a component factory and load the QML script. print("Hello") self.component = QQmlComponent(self.appLabel.engine()) self.component.loadUrl(QUrl('qml/TextStatusFly.qml')) print("Hello2") self.statuswidget = self.component.create(self.appLabel.rootContext()) print("Hello3") self.statuswidget.setParentItem(self.appLabel.rootObject()) self.statuswidget.setParent(self.appLabel.rootObject()) print("Hello4") #statuswidget.setProperty("targetX", 100) self.statuswidget.setProperty("objectName", "textStatusBar") print("Hello5") self.appLabel.rootContext().setContextProperty('textStatusBar', self.statuswidget) self.statuswidget.setProperty("parentSet", True) def update_url_signal(self, url): print(" ** Updating URL: %s" % url) #self.pbengine.on_change_url.disconnect() #self.pbengine.on_connect_signal.disconnect() self.appLabel.rootContext().setContextProperty('textStatusBar', None) self.appLabel.setSource(QUrl()) self.appLabel.engine().clearComponentCache() self.appLabel.setSource(QUrl(url)) self.setup_text_status_fly_component() self.appLabel.show() # Reconnect #self.pbengine.on_change_url.connect(self.update_url_signal) #self.pbengine.on_connect_signal.connect(self.connect_signal) def connect_signal(self, signal, target): print(" ** Binding signal %s to target %s!" % (str(signal), target)) print(" ** (getattr(self.appLabel, target) = %s)" % (str(getattr(self.appLabel.rootObject(), target)))) signal.connect(getattr(self.appLabel.rootObject(), target))
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)
# 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)
def newUUID(self): return QUuid.createUuid().toString() if __name__ == '__main__': import os import sys app = QGuiApplication(sys.argv) app.setLayoutDirection(Qt.RightToLeft); view = QQuickView() context = view.rootContext() view.engine().setOfflineStoragePath(".") exutil = LauncherEXUtils() qmlRegisterType(LauncherEXUtils, 'ExUtils', 1, 0, 'ExUtils') qmlRegisterType(Bozorgrah,'Bozorgrah',1,0,'Bozorgrah') context.setContextProperty('exutils',exutil) view.setResizeMode(QQuickView.SizeRootObjectToView) try: approot = os.path.dirname(os.path.abspath(__file__)) except NameError: # We are the main py2exe script, not a module approot = os.path.dirname(os.path.abspath(sys.argv[0])) print(approot) view.setSource( QUrl.fromLocalFile( os.path.join(approot,'qml\\app.qml')))
## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ## $QT_END_LICENSE$ ## ############################################################################# import sys import os.path from PyQt5.QtCore import QUrl from PyQt5.QtGui import QGuiApplication from PyQt5.QtQuick import QQuickView #animation 폴더의 animation_rc 와 shared 폴더의 shared_rc를 import해온다. from shared_rc import * from animation_rc import * if len(sys.argv) is 2:# 실행 옵션으로 파이썬도움말 절대경로 제공시 os.chdir(sys.argv[1]) app = QGuiApplication(sys.argv) view = QQuickView() view.engine().quit.connect(app.quit) view.setSource(QUrl('animation.qml')) view.show() sys.exit(app.exec_())
from controllers.binarizeController import BinarizeController from controllers.morphologyController import MorphologyController from controllers.segmentationController import SegmentationController if __name__ == '__main__': # Create main app myApp = QApplication(sys.argv) myApp.setWindowIcon(QIcon('./images/icon.png')) # Create a View and set its properties appView = QQuickView() appView.setMinimumHeight(640) appView.setMinimumWidth(1024) appView.setTitle('roadLaneFinding') engine = appView.engine() engine.quit.connect(myApp.quit) context = engine.rootContext() # add paths # appDir = os.getcwd() # print(QDir.currentPath()) appDir = 'file:///' + QDir.currentPath() # print(appDir) # # print('appDir:', appDir) # appDir = 'file:///h:/QtDocuments/AOI' # print(appDir) context.setContextProperty('appDir', appDir) # add controllers mainController = MainController()