test.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import sys,os,subprocess,time,traceback
  2. import random
  3. from PySide2 import QtCore
  4. from PySide2.QtWidgets import *
  5. from PySide2.QtGui import *
  6. class Worker(QtCore.QRunnable):
  7. """Worker thread for running background tasks."""
  8. def __init__(self, fn, *args, **kwargs):
  9. super(Worker, self).__init__()
  10. # Store constructor arguments (re-used for processing)
  11. self.fn = fn
  12. self.args = args
  13. self.kwargs = kwargs
  14. self.signals = WorkerSignals()
  15. self.kwargs['progress_callback'] = self.signals.progress
  16. @QtCore.Slot()
  17. def run(self):
  18. try:
  19. result = self.fn(
  20. *self.args, **self.kwargs,
  21. )
  22. except:
  23. traceback.print_exc()
  24. exctype, value = sys.exc_info()[:2]
  25. self.signals.error.emit((exctype, value, traceback.format_exc()))
  26. else:
  27. self.signals.result.emit(result)
  28. finally:
  29. self.signals.finished.emit()
  30. class WorkerSignals(QtCore.QObject):
  31. """
  32. Defines the signals available from a running worker thread.
  33. Supported signals are:
  34. finished
  35. No data
  36. error
  37. `tuple` (exctype, value, traceback.format_exc() )
  38. result
  39. `object` data returned from processing, anything
  40. """
  41. finished = QtCore.Signal()
  42. error = QtCore.Signal(tuple)
  43. result = QtCore.Signal(object)
  44. progress = QtCore.Signal(int)
  45. class App(QDialog):
  46. """GUI Application using PySide2 widgets"""
  47. def __init__(self):
  48. QDialog.__init__(self)
  49. self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
  50. self.setGeometry(QtCore.QRect(200, 200, 500, 500))
  51. self.threadpool = QtCore.QThreadPool()
  52. layout = QVBoxLayout(self)
  53. self.setLayout(layout)
  54. self.startbutton = QPushButton('START')
  55. self.startbutton.clicked.connect(self.run)
  56. layout.addWidget(self.startbutton)
  57. self.stopbutton = QPushButton('STOP')
  58. self.stopbutton.clicked.connect(self.stop)
  59. layout.addWidget(self.stopbutton)
  60. self.progressbar = QProgressBar(self)
  61. self.progressbar.setRange(0,1)
  62. layout.addWidget(self.progressbar)
  63. self.info = QTextEdit(self)
  64. self.info.append('Hello')
  65. layout.addWidget(self.info)
  66. return
  67. def progress_fn(self, msg):
  68. """Update progress"""
  69. self.info.append(str(msg))
  70. return
  71. def run_threaded_process(self, process, progress_fn, on_complete):
  72. """Execute a function in the background with a worker"""
  73. worker = Worker(fn=process)
  74. self.threadpool.start(worker)
  75. worker.signals.finished.connect(on_complete)
  76. worker.signals.progress.connect(progress_fn)
  77. self.progressbar.setRange(0,0)
  78. return
  79. def run(self):
  80. """call process"""
  81. self.stopped = False
  82. self.run_threaded_process(self.test, self.progress_fn, self.completed)
  83. def stop(self):
  84. self.stopped=True
  85. return
  86. def completed(self):
  87. self.progressbar.setRange(0,1)
  88. return
  89. def test(self, progress_callback):
  90. """Do some process here"""
  91. total = 500
  92. for i in range(0,total):
  93. time.sleep(.2)
  94. x = random.randint(1,1e4)
  95. progress_callback.emit(x)
  96. if self.stopped == True:
  97. return
  98. app = QApplication([])
  99. xapp = App()
  100. xapp.show()
  101. sys.exit(app.exec_())