def __init__(self, plugin, serverName="Qgis2threejs", perspective=False): layer = plugin.iface.activeLayer() title = "[2.5D] " + layer.name() if layer else "" QgsPluginLayer.__init__(self, Qgis2threejsLayer.LAYER_TYPE, title) if layer is None: return self.setValid(True) self.plugin = plugin self.iface = plugin.iface self.objectTypeManager = plugin.objectTypeManager self.pluginManager = plugin.pluginManager self.renderer = Qgis2threejs25DRenderer() #self.id()) self.renderer.setup(self, serverName, perspective) self.renderer.setLayers([self.iface.activeLayer()]) # set custom properties #self.setCustomProperty("title", title) # set extent #self.setExtent(QgsRectangle(-layerDef.TSIZE1, -layerDef.TSIZE1, layerDef.TSIZE1, layerDef.TSIZE1)) # set styles self.setTransparency(0) self.setBlendModeByName(self.DEFAULT_BLEND_MODE) self.setSmoothRender(self.DEFAULT_SMOOTH_RENDER) # multi-thread if self.iface: self.statusSignal.connect(self.showStatusMessageSlot) self.messageBarSignal.connect(self.showMessageBarSlot) logMessage("Launching Qgis2threejs Renderer...") this_dir = os.path.dirname(QFile.decodeName(__file__)) parent = self.iface.mainWindow() p = QProcess(parent) if os.name == "nt": os.system("start cmd.exe /c {0} -r -n {1}".format(os.path.join(this_dir, "q3drenderer.bat"), serverName)) return cmd = r"C:\Python34\python.exe" else: cmd = "python3" p.start(cmd, [os.path.join(this_dir, "q3dapplication.py"), "-r", "-n", serverName]) if not p.waitForStarted(): logMessage("Cannot launch Qgis2threejs Renderer (code: {0}).".format(p.error()))
class GUIProcess(QObject): """An external process which shows notifications in the GUI. Args: cmd: The command which was started. args: A list of arguments which gets passed. verbose: Whether to show more messages. _started: Whether the underlying process is started. _proc: The underlying QProcess. _what: What kind of thing is spawned (process/editor/userscript/...). Used in messages. Signals: error/finished/started signals proxied from QProcess. """ error = pyqtSignal(QProcess.ProcessError) finished = pyqtSignal(int, QProcess.ExitStatus) started = pyqtSignal() def __init__(self, what, *, verbose=False, additional_env=None, parent=None): super().__init__(parent) self._what = what self.verbose = verbose self._started = False self.cmd = None self.args = None self._proc = QProcess(self) self._proc.error.connect(self.on_error) self._proc.error.connect(self.error) self._proc.finished.connect(self.on_finished) self._proc.finished.connect(self.finished) self._proc.started.connect(self.on_started) self._proc.started.connect(self.started) if additional_env is not None: procenv = QProcessEnvironment.systemEnvironment() for k, v in additional_env.items(): procenv.insert(k, v) self._proc.setProcessEnvironment(procenv) @pyqtSlot(QProcess.ProcessError) def on_error(self, error): """Show a message if there was an error while spawning.""" msg = ERROR_STRINGS[error] message.error("Error while spawning {}: {}".format(self._what, msg)) @pyqtSlot(int, QProcess.ExitStatus) def on_finished(self, code, status): """Show a message when the process finished.""" self._started = False log.procs.debug("Process finished with code {}, status {}.".format( code, status)) if status == QProcess.CrashExit: message.error("{} crashed!".format(self._what.capitalize())) elif status == QProcess.NormalExit and code == 0: if self.verbose: message.info("{} exited successfully.".format( self._what.capitalize())) else: assert status == QProcess.NormalExit # We call this 'status' here as it makes more sense to the user - # it's actually 'code'. message.error("{} exited with status {}.".format( self._what.capitalize(), code)) stderr = bytes(self._proc.readAllStandardError()).decode('utf-8') stdout = bytes(self._proc.readAllStandardOutput()).decode('utf-8') if stdout: log.procs.error("Process stdout:\n" + stdout.strip()) if stderr: log.procs.error("Process stderr:\n" + stderr.strip()) @pyqtSlot() def on_started(self): """Called when the process started successfully.""" log.procs.debug("Process started.") assert not self._started self._started = True def _pre_start(self, cmd, args): """Prepare starting of a QProcess.""" if self._started: raise ValueError("Trying to start a running QProcess!") self.cmd = cmd self.args = args fake_cmdline = ' '.join(shlex.quote(e) for e in [cmd] + list(args)) log.procs.debug("Executing: {}".format(fake_cmdline)) if self.verbose: message.info('Executing: ' + fake_cmdline) def start(self, cmd, args, mode=None): """Convenience wrapper around QProcess::start.""" log.procs.debug("Starting process.") self._pre_start(cmd, args) if mode is None: self._proc.start(cmd, args) else: self._proc.start(cmd, args, mode) def start_detached(self, cmd, args, cwd=None): """Convenience wrapper around QProcess::startDetached.""" log.procs.debug("Starting detached.") self._pre_start(cmd, args) ok, _pid = self._proc.startDetached(cmd, args, cwd) if ok: log.procs.debug("Process started.") self._started = True else: message.error("Error while spawning {}: {}.".format( self._what, self._proc.error())) def exit_status(self): return self._proc.exitStatus()
class GUIProcess(QObject): """An external process which shows notifications in the GUI. Args: cmd: The command which was started. args: A list of arguments which gets passed. verbose: Whether to show more messages. _started: Whether the underlying process is started. _proc: The underlying QProcess. _what: What kind of thing is spawned (process/editor/userscript/...). Used in messages. Signals: error/finished/started signals proxied from QProcess. """ error = pyqtSignal(QProcess.ProcessError) finished = pyqtSignal(int, QProcess.ExitStatus) started = pyqtSignal() def __init__(self, what, *, verbose=False, additional_env=None, parent=None): super().__init__(parent) self._what = what self.verbose = verbose self._started = False self.cmd = None self.args = None self._proc = QProcess(self) self._proc.error.connect(self.on_error) self._proc.error.connect(self.error) self._proc.finished.connect(self.on_finished) self._proc.finished.connect(self.finished) self._proc.started.connect(self.on_started) self._proc.started.connect(self.started) if additional_env is not None: procenv = QProcessEnvironment.systemEnvironment() for k, v in additional_env.items(): procenv.insert(k, v) self._proc.setProcessEnvironment(procenv) @pyqtSlot(QProcess.ProcessError) def on_error(self, error): """Show a message if there was an error while spawning.""" msg = ERROR_STRINGS[error] message.error("Error while spawning {}: {}".format(self._what, msg)) @pyqtSlot(int, QProcess.ExitStatus) def on_finished(self, code, status): """Show a message when the process finished.""" self._started = False log.procs.debug("Process finished with code {}, status {}.".format( code, status)) if status == QProcess.CrashExit: message.error("{} crashed!".format(self._what.capitalize())) elif status == QProcess.NormalExit and code == 0: if self.verbose: message.info("{} exited successfully.".format( self._what.capitalize())) else: assert status == QProcess.NormalExit # We call this 'status' here as it makes more sense to the user - # it's actually 'code'. message.error("{} exited with status {}.".format( self._what.capitalize(), code)) stderr = bytes(self._proc.readAllStandardError()).decode('utf-8') stdout = bytes(self._proc.readAllStandardOutput()).decode('utf-8') if stdout: log.procs.error("Process stdout:\n" + stdout.strip()) if stderr: log.procs.error("Process stderr:\n" + stderr.strip()) @pyqtSlot() def on_started(self): """Called when the process started successfully.""" log.procs.debug("Process started.") assert not self._started self._started = True def _pre_start(self, cmd, args): """Prepare starting of a QProcess.""" if self._started: raise ValueError("Trying to start a running QProcess!") self.cmd = cmd self.args = args fake_cmdline = ' '.join(shlex.quote(e) for e in [cmd] + list(args)) log.procs.debug("Executing: {}".format(fake_cmdline)) if self.verbose: message.info('Executing: ' + fake_cmdline) def start(self, cmd, args, mode=None): """Convenience wrapper around QProcess::start.""" log.procs.debug("Starting process.") self._pre_start(cmd, args) if mode is None: self._proc.start(cmd, args) else: self._proc.start(cmd, args, mode) self._proc.closeWriteChannel() def start_detached(self, cmd, args, cwd=None): """Convenience wrapper around QProcess::startDetached.""" log.procs.debug("Starting detached.") self._pre_start(cmd, args) ok, _pid = self._proc.startDetached(cmd, args, cwd) if ok: log.procs.debug("Process started.") self._started = True else: message.error("Error while spawning {}: {}".format( self._what, ERROR_STRINGS[self._proc.error()])) def exit_status(self): return self._proc.exitStatus()
class runV2raycore(QObject): """ you should emit a signal to start or stop a program. """ start = pyqtSignal() stop = pyqtSignal() def __init__(self, outputTextEdit, v2rayPath="v2ray", v2rayOption="", bridgetreasureChest=False): super().__init__() self.outputTextEdit = outputTextEdit self.v2rayPath = v2rayPath self.v2rayOption = v2rayOption self.bridgetreasureChest = bridgetreasureChest if not self.bridgetreasureChest: from bridgehouse.extension import bridgetreasureChest self.bridgetreasureChest = bridgetreasureChest.bridgetreasureChest( ) self.v2rayProcess = QProcess() self.v2rayProcess.setProcessChannelMode(QProcess.MergedChannels) self.v2rayProcess.setProcessEnvironment( QProcessEnvironment.systemEnvironment()) self.v2rayProcess.readyRead.connect(self.setoutputTextEdit) self.v2rayProcess.started.connect(self.oncreatePIDFile) self.start.connect(self.onstart) self.stop.connect(self.onstop) self.translate = QCoreApplication.translate self.pidFile = ".v2rayPID" def onstart(self): if (self.v2rayProcess.state() == QProcess.NotRunning): self.outputTextEdit.clear() command = self.translate("runV2raycore", "v2ray file path had no seted.") if (self.v2rayPath): checkSpaces = re.search(" ", self.v2rayPath) if checkSpaces: # in fact, you can just keep this line. # do not need check spaces command = '"' + self.v2rayPath + '" ' + self.v2rayOption else: command = "{} {}".format(self.v2rayPath, self.v2rayOption) self.killOrphanProcess() self.v2rayProcess.start(command, QIODevice.ReadWrite) self.outputTextEdit.insertPlainText("{}\n\n".format(command)) if (self.v2rayProcess.state() == QProcess.NotRunning): self.outputTextEdit.moveCursor(QTextCursor.End) self.outputTextEdit.append("\n") self.outputTextEdit.insertPlainText(str( "{}\n".format(command))) self.outputTextEdit.insertPlainText( str( self.translate("runV2raycore", "{} Error Code:{}").format( self.v2rayProcess.errorString(), self.v2rayProcess.error()))) self.outputTextEdit.moveCursor(QTextCursor.End) self.outputTextEdit.textChanged.connect(self.getV2raycoreVersion) def killOrphanProcess(self): openFile = QFileInfo(self.pidFile) fileName = openFile.fileName() if QFile.exists(fileName): openFile = QFile(fileName) else: return v2rayPID = None try: openFile.open(QIODevice.ReadOnly | QIODevice.Text) v2rayPID = str(openFile.readAll(), "utf-8") except Exception: pass try: os.kill(int(v2rayPID), signal.SIGTERM) except Exception: pass def oncreatePIDFile(self): if self.v2rayProcess.state() == QProcess.NotRunning: return outFile = QFileInfo(self.pidFile) fileName = outFile.fileName() if QFile.exists(fileName): QFile.remove(fileName) outFile = QFile(fileName) v2rayPID = str(self.v2rayProcess.processId()) qDebug("process ID is: {}".format(v2rayPID)) try: outFile.open(QIODevice.WriteOnly | QIODevice.Text) outFile.write(codecs.encode(v2rayPID, "utf-8")) except Exception: pass outFile.close() def getV2raycoreVersion(self): text = self.outputTextEdit.toPlainText() version = re.findall("V2Ray v\d\.\d{1,2}", text) failtostart = re.findall("Failed to start App", text) if (version): version = version[0].split(" ")[1] self.bridgetreasureChest.setV2raycoreVersion(version) if (failtostart): self.outputTextEdit.textChanged.disconnect( self.getV2raycoreVersion) self.onstop() def onstop(self): if (self.v2rayProcess.state() == QProcess.Running): self.v2rayProcess.close() self.v2rayProcess.kill() self.outputTextEdit.moveCursor(QTextCursor.End) self.outputTextEdit.append("\n\n") self.outputTextEdit.insertPlainText( str( self.translate("runV2raycore", "{} is stop now...").format( self.v2rayPath))) self.outputTextEdit.insertPlainText( str( self.translate("runV2raycore", "\n{} is ready to run...").format( self.v2rayPath))) self.outputTextEdit.moveCursor(QTextCursor.End) def setoutputTextEdit(self): self.outputTextEdit.moveCursor(QTextCursor.End) self.outputTextEdit.insertPlainText( str(self.v2rayProcess.readAllStandardOutput(), "utf-8")) self.outputTextEdit.insertPlainText( str(self.v2rayProcess.readAllStandardError(), "utf-8")) self.outputTextEdit.moveCursor(QTextCursor.End)