|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2024 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing a QProcess derived class with a timeout and convenience signals. |
|
8 """ |
|
9 |
|
10 from PyQt6.QtCore import QProcess, QTimer, pyqtSignal, pyqtSlot |
|
11 |
|
12 |
|
13 class EricProcess(QProcess): |
|
14 """ |
|
15 Class implementing a QProcess derived class with a timeout and convenience signals |
|
16 succeeded and failed. |
|
17 |
|
18 @signal failed() emitted to indicate a process failure |
|
19 @signal succeeded() emitted to indicate that the process finished successfully |
|
20 @signal timeout() emitted to indicate the expiry of the configured timeout value |
|
21 """ |
|
22 |
|
23 failed = pyqtSignal() |
|
24 succeeded = pyqtSignal() |
|
25 timeout = pyqtSignal() |
|
26 |
|
27 def __init__(self, timeout=30000, parent=None): |
|
28 """ |
|
29 Constructor |
|
30 |
|
31 @param timeout timeout value in milliseconds. If the process does not finish |
|
32 within this interval, it is killed. (defaults to 30000) |
|
33 @type int (optional) |
|
34 @param parent reference to the parent object (defaults to None) |
|
35 @type QObject (optional) |
|
36 """ |
|
37 super().__init__(parent=parent) |
|
38 |
|
39 self.started.connect(self.__started) |
|
40 self.finished.connect(self.__finished) |
|
41 |
|
42 self.__timeoutTimer = QTimer(self) |
|
43 self.__timeoutTimer.setInterval(timeout) |
|
44 self.__timeoutTimer.timeout.connect(self.__timeout) |
|
45 |
|
46 self.__timedOut = False |
|
47 |
|
48 def timedOut(self): |
|
49 """ |
|
50 Public method to test, if the process timed out. |
|
51 |
|
52 @return flag indicating a timeout |
|
53 @rtype bool |
|
54 """ |
|
55 return self.__timedOut |
|
56 |
|
57 def timeoutInterval(self): |
|
58 """ |
|
59 Public method to get the process timeout interval. |
|
60 |
|
61 @return process timeout interval in milliseconds |
|
62 @rtype int |
|
63 """ |
|
64 return self.__timeoutTimer.interval() |
|
65 |
|
66 @pyqtSlot() |
|
67 def __timeout(self): |
|
68 """ |
|
69 Private slot to handle the timer interval exoiration. |
|
70 """ |
|
71 self.__timeoutTimer.stop() |
|
72 self.__timedOut = True |
|
73 self.kill() |
|
74 |
|
75 self.timeout.emit() |
|
76 |
|
77 @pyqtSlot() |
|
78 def __started(self): |
|
79 """ |
|
80 Private slot handling the process start. |
|
81 """ |
|
82 self.__timedOut = False |
|
83 self.__timeoutTimer.start() |
|
84 |
|
85 @pyqtSlot(int, QProcess.ExitStatus) |
|
86 def __finished(self, exitCode, exitStatus): |
|
87 """ |
|
88 Private slot handling the end of the process. |
|
89 |
|
90 @param exitCode exit code of the process (0 = success) |
|
91 @type int |
|
92 @param exitStatus exit status of the process |
|
93 @type QProcess.ExitStatus |
|
94 """ |
|
95 self.__timeoutTimer.stop() |
|
96 |
|
97 if exitStatus == QProcess.ExitStatus.CrashExit or exitCode != 0: |
|
98 self.failed.emit() |
|
99 else: |
|
100 self.succeeded.emit() |