Advertisement
Guest User

Untitled

a guest
Mar 25th, 2019
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.53 KB | None | 0 0
  1. import math
  2. import sys
  3. import asyncio
  4. from functools import partial, wraps
  5. from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QGridLayout, QProgressBar, QErrorMessage
  6. from PyQt5.QtCore import Qt
  7. from quamash import QEventLoop
  8. import traceback
  9.  
  10.  
  11. def display_error(err):
  12. app = QApplication.instance()
  13. window = app.activeWindow()
  14. dialog = QErrorMessage(window)
  15. dialog.setWindowModality(Qt.WindowModal)
  16. dialog.setWindowTitle("Error")
  17. dialog.showMessage(err)
  18.  
  19.  
  20. def slot_coroutine(async_func):
  21. if not asyncio.iscoroutinefunction(async_func):
  22. raise RuntimeError('Must be a coroutine!')
  23.  
  24. def log_error(future):
  25. try:
  26. future.result()
  27. except Exception as err:
  28. display_error(traceback.format_exc())
  29.  
  30. @wraps(async_func)
  31. def wrapper(self, *args):
  32. loop = asyncio.get_event_loop()
  33. future = loop.create_task(async_func(self, *args[:-1]))
  34. future.add_done_callback(log_error)
  35. return wrapper
  36.  
  37. class MyWidget(QWidget):
  38.  
  39. def __init__(self, parent=None):
  40. super().__init__(parent)
  41. layout = QGridLayout()
  42.  
  43. self.pairs = []
  44. for i in range(10):
  45. b = QPushButton('Countdown: &%d' % i) # NB cannot use the clicked kwarg!
  46. b.clicked.connect(partial(self.on_click_coroutine, i))
  47. p = QProgressBar(visible=False)
  48. layout.addWidget(b, i, 0)
  49. layout.addWidget(p, i, 1)
  50. self.pairs.append((b, p))
  51.  
  52. self.setLayout(layout)
  53.  
  54. @slot_coroutine
  55. async def on_click_coroutine(self, i):
  56. """ This is connected to the button's signal via button.clicked.connect(...). It is
  57. a coroutine but the decorator wraps it, executes it as returns a function.
  58. """
  59. if i == 2:
  60. raise ValueError('Blah!! Two always fails.')
  61. b, p = self.pairs[i]
  62. await self.do_countdown(b, p, i)
  63.  
  64. @staticmethod
  65. async def do_countdown(b, p, n):
  66.  
  67. b.setEnabled(False)
  68. p.setVisible(True)
  69.  
  70. i = n * 100
  71. p.setMaximum(i)
  72.  
  73. while i >= 0:
  74.  
  75. await asyncio.sleep(0.01)
  76.  
  77. p.setValue(i)
  78. b.setText('Countdown: %d' % math.ceil(i/100))
  79. i -= 1
  80.  
  81. b.setText('Countdown: &%d' % n)
  82. b.setEnabled(True)
  83. p.setVisible(False)
  84.  
  85.  
  86. def main():
  87. app = QApplication(sys.argv)
  88. loop = QEventLoop(app)
  89. asyncio.set_event_loop(loop) # NEW must set the event loop
  90.  
  91. w = MyWidget()
  92. w.show()
  93.  
  94. with loop:
  95. loop.run_forever()
  96.  
  97. if __name__ == '__main__':
  98. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement