diff -r e164b9ad3819 -r 550e5ea385cb ProjectFlask/RunServerDialog.py --- a/ProjectFlask/RunServerDialog.py Mon Nov 09 20:00:56 2020 +0100 +++ b/ProjectFlask/RunServerDialog.py Tue Nov 10 19:38:00 2020 +0100 @@ -7,7 +7,9 @@ Module implementing a dialog to run the Flask server. """ -from PyQt5.QtCore import pyqtSlot, QProcess +import re + +from PyQt5.QtCore import pyqtSlot, Qt, QProcess, QTimer from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton from E5Gui import E5MessageBox @@ -31,9 +33,13 @@ self.__process = None + self.__ansiRe = re.compile("(\\x1b\[\d+m)") + self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) + + self.__defaultTextFormat = self.outputEdit.currentCharFormat() def startServer(self, command, workdir, env): """ @@ -48,14 +54,13 @@ @return flag indicating a successful start @rtype bool """ - self.errorsEdit.hide() - self.__process = QProcess() - self.__process.readyReadStandardOutput.connect(self.__readStdOut) - self.__process.readyReadStandardError.connect(self.__readStdErr) - self.__process.finished.connect(self.__processFinished) self.__process.setProcessEnvironment(env) self.__process.setWorkingDirectory(workdir) + self.__process.setProcessChannelMode(QProcess.MergedChannels) + + self.__process.readyReadStandardOutput.connect(self.__readStdOut) + self.__process.finished.connect(self.__processFinished) self.__process.start(command, ["run"]) ok = self.__process.waitForStarted(10000) @@ -78,7 +83,8 @@ @param evt reference to the close event @type QCloseEvent """ - # TODO: not implemented yet + self.__cancel() + evt.accept() @pyqtSlot(QAbstractButton) def on_buttonBox_clicked(self, button): @@ -100,27 +106,38 @@ """ if self.__process is not None: out = str(self.__process.readAllStandardOutput(), "utf-8") - self.outputEdit.appendPlainText(out) - - @pyqtSlot() - def __readStdErr(self): - """ - Private slot to add the server process errors to the errors pane. - """ - if self.__process is not None: - err = str(self.__process.readAllStandardError(), "utf-8") - self.errorsEdit.appendPlainText(err) - - self.errorsEdit.show() + for txt in self.__ansiRe.split(out): + if txt.startswith("\x1b["): + # TODO: process ANSI escape sequences for coloring + pass + else: + self.outputEdit.insertPlainText(txt) @pyqtSlot() def __processFinished(self): - # TODO: implement it - pass + """ + Private slot handling the finishing of the server process. + """ + if ( + self.__process is not None and + self.__process.state() != QProcess.NotRunning + ): + self.__process.terminate() + QTimer.singleShot(2000, self.__process.kill) + self.__process.waitForFinished(3000) + + self.__process = None + + + self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) + self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) + self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) + self.buttonBox.button(QDialogButtonBox.Close).setFocus( + Qt.OtherFocusReason) @pyqtSlot() def __cancel(self): """ Private slot to cancel the running server. """ - # TODO: not implemented yet + self.__processFinished()