|
14 | 14 |
|
15 | 15 | import psutil |
16 | 16 | from PyQt6 import QtCore |
17 | | -from PyQt6.QtCore import QFileInfo, QThread, pyqtSignal |
| 17 | +from PyQt6.QtCore import QFileInfo, QObject, QThread, pyqtSignal |
18 | 18 | from PyQt6.QtWidgets import QApplication, QFileDialog, QSystemTrayIcon |
19 | 19 |
|
20 | 20 | from vorta.borg._compatibility import BorgCompatibility |
|
31 | 31 | _network_status_monitor = None |
32 | 32 |
|
33 | 33 |
|
| 34 | +class AsyncRunner(QObject): |
| 35 | + ''' |
| 36 | + Wrapper to run functions asynchronously from GUI thread, based on |
| 37 | + https://gist.github.com/andgineer/026a617528c5740da24ec984ac282ee6#file-universal_decorator-py |
| 38 | +
|
| 39 | + NB Only apply it to void functions, otherwise return values will be lost. |
| 40 | + ''' |
| 41 | + runner_thread = None |
| 42 | + |
| 43 | + def __init__(self, orig_func): |
| 44 | + super(AsyncRunner, self).__init__() |
| 45 | + self.orig_func = orig_func |
| 46 | + self.__name__ = "AsyncRunner" |
| 47 | + |
| 48 | + def __call__(self, *args): |
| 49 | + return self.orig_func(*args) |
| 50 | + |
| 51 | + def __get__(self, wrapped_instance, owner): |
| 52 | + return AsyncRunner.Helper(self, wrapped_instance) |
| 53 | + |
| 54 | + class Helper(QObject): |
| 55 | + def __init__(self, decorator_instance, wrapped_instance): |
| 56 | + super(AsyncRunner.Helper, self).__init__() |
| 57 | + self.decorator_instance = decorator_instance |
| 58 | + self.wrapped_instance = wrapped_instance |
| 59 | + |
| 60 | + def __call__(self, *args, **kwargs): |
| 61 | + global runner_thread |
| 62 | + runner_thread = AsyncRunner.Runner(self.decorator_instance, self.wrapped_instance, *args, **kwargs) |
| 63 | + runner_thread.start() |
| 64 | + |
| 65 | + class Runner(QtCore.QThread): |
| 66 | + def __init__(self, decorator_instance, wrapped_instance, *args, **kwargs): |
| 67 | + QtCore.QThread.__init__(self) |
| 68 | + self.decorator_instance = decorator_instance |
| 69 | + self.wrapped_instance = wrapped_instance |
| 70 | + self.args = args |
| 71 | + self.kwargs = kwargs |
| 72 | + |
| 73 | + def run(self): |
| 74 | + self.decorator_instance(self.wrapped_instance, *self.args, **self.kwargs) |
| 75 | + self.terminate() |
| 76 | + self.wait() |
| 77 | + |
| 78 | + |
34 | 79 | class FilePathInfoAsync(QThread): |
35 | 80 | signal = pyqtSignal(str, str, str) |
36 | 81 |
|
|
0 commit comments