2

I'm using python with qt and i cannot find out a way to fire a signal when Qprocess exit normally, According to Pyqt documentation finished() signal can take 2 arguments exitCode and exitStatus

This is what Pyqt documentation says about finished() signal

http://pyqt.sourceforge.net/Docs/PyQt4/qprocess.html#finished

void finished (int, ::QProcess::ExitStatus)

This is the default overload of this signal.

This signal is emitted when the process finishes. exitCode is the exit code of the process, and exitStatus is the exit status. After the process has finished, the buffers in QProcess are still intact. You can still read any data that the process may have written before it finished.

QProcess.ExitStatus

This enum describes the different exit statuses of QProcess.

Constant..................Value.........Description

QProcess.NormalExit....... 0.......The process exited normally.

QProcess.CrashExit........ 1.......The process crashed.

I tried to use this syntax but it did't work

self.process.finished(0,QProcess_ExitStatus=0).connect(self.status)

Remark:

Status is just as symbol for any slot (any action ) not something specific

Update:

To get a sense of the problem I've more than one process (Think of it as queue) i need python to execute the first process and only move to the next one if the previous process exits normally not forced to exit using kill() or terminate()

Thanks in advance

Mohamed sayed
  • 23
  • 1
  • 6
  • `self.process.finished[int, QProcess.ExitStatus].connect(self.status)` or just `self.process.finished.connect(self.status)` (which gets the default). – ekhumoro Dec 21 '18 at 00:27
  • Thanks this syntax was helpful i used self.process = QtCore.QProcess(self) self.process.finished[int,self.process.ExitStatus].connect(status) and fixed the problem but still one thing i can't figure it out ,why python understand this syntax in such way and i didn't gave it any value for ExitStatus to it him know whether i need to execute slot for NormalExit or CrashExit – Mohamed sayed Dec 22 '18 at 12:46
  • You don't need to do that: just use `self.process.finished.connect(self.status)`, and it will do the right thing. The `QProcess` will automatically send the correct exit code and status when it emits the signal. So you just need to connect `finished` to a slot that takes two arguments, and then check the value of the arguments to decide what your code should do next. – ekhumoro Dec 22 '18 at 16:35

1 Answers1

1

You do not have to point to the symbol in the connection but in the slot with the help of pyqtSlot.

from PyQt4 import QtCore

class Helper(QtCore.QObject):
    def __init__(self, parent=None):
        super(Helper, self).__init__(parent)
        self.process = QtCore.QProcess(self)
        self.process.start("ping -c 4 google.com")
        self.process.finished.connect(self.status)

    @QtCore.pyqtSlot(int, QtCore.QProcess.ExitStatus)
    def status(self, exitCode, exitStatus):
        print(exitCode, exitStatus)
        QtCore.QCoreApplication.quit()

if __name__ == '__main__':
    import sys
    app = QtCore.QCoreApplication(sys.argv)
    h = Helper()
    sys.exit(app.exec_())

Update:

from PyQt4 import QtCore

class Helper(QtCore.QObject):
    def __init__(self, parent=None):
        super(Helper, self).__init__(parent)
        self.process = QtCore.QProcess(self)
        self.process.start("ping -c 4 google.com")
        self.process.finished.connect(self.on_finished)

    @QtCore.pyqtSlot(int, QtCore.QProcess.ExitStatus)
    def on_finished(self, exitCode, exitStatus):
        if exitStatus == QtCore.QProcess.NormalExit:
            self.status()

    def status(self):
        print("status")
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • my mistake if the question was not clear enough i wrote (status) just as symbol for any slot (any action ) not something specific , i really need to execute that slot only if the process exits normally not forced to exit using terminate() or kill() – Mohamed sayed Dec 21 '18 at 10:19
  • @Mohamedsayed the decorator pyqtSlot () points to the signature that accepts the slot in the connections, in the case of finished as it indicates the docs is overloaded, that is to say to 2 signals with the same name but that transmits different information, so to indicate which of the Signs are required to use must be explicit. Also as an advantage is that the connection is given on the C ++ side so it is faster and less expensive in addition to other benefits. – eyllanesc Dec 21 '18 at 15:11
  • Thanks very much it made my code work , one last thing seems strange to me and i did not understand well is @QtCore.pyqtSlot(int, QtCore.QProcess.ExitStatus) could you explain more – Mohamed sayed Dec 21 '18 at 15:58
  • @Mohamedsayed I explained, have you read my previous comment?: *the decorator `pyqtSlot()` points to the signature that accepts the slot in the connections, in the case of finished as it indicates the docs is overloaded, that is to say to 2 signals with the same name but that transmits different information, so to indicate which of the Signals are required to use must be explicit. Also as an advantage is that the connection is given on the C ++ side so it is faster and less expensive in addition to other benefit* – eyllanesc Dec 21 '18 at 16:01
  • I don't know why pyqt4 defines two overloads. because [qt4 certainly doesn't](https://doc.qt.io/qt-5/qprocess.html#signals). There is therefore no point in selecting the overload, and the slot decorator makes no difference either. QProcess can only ever emit `finished(int exitCode, QProcess::ExitStatus exitStatus)`, so you should just use `self.process.finished.connect(self.status)` (which selects the default). This seems to be a minor bug that was fixed in pyqt5, where `QProcess` now only has one overload of `finished`. – ekhumoro Dec 22 '18 at 16:30