• <tfoot id='mo6rf'></tfoot>
  • <legend id='mo6rf'><style id='mo6rf'><dir id='mo6rf'><q id='mo6rf'></q></dir></style></legend>

        • <bdo id='mo6rf'></bdo><ul id='mo6rf'></ul>

        <small id='mo6rf'></small><noframes id='mo6rf'>

      1. <i id='mo6rf'><tr id='mo6rf'><dt id='mo6rf'><q id='mo6rf'><span id='mo6rf'><b id='mo6rf'><form id='mo6rf'><ins id='mo6rf'></ins><ul id='mo6rf'></ul><sub id='mo6rf'></sub></form><legend id='mo6rf'></legend><bdo id='mo6rf'><pre id='mo6rf'><center id='mo6rf'></center></pre></bdo></b><th id='mo6rf'></th></span></q></dt></tr></i><div id='mo6rf'><tfoot id='mo6rf'></tfoot><dl id='mo6rf'><fieldset id='mo6rf'></fieldset></dl></div>

        在单独的线程中运行异步循环,信号来自和循环

        时间:2023-08-06
      2. <tfoot id='vukC3'></tfoot>

      3. <legend id='vukC3'><style id='vukC3'><dir id='vukC3'><q id='vukC3'></q></dir></style></legend>
        <i id='vukC3'><tr id='vukC3'><dt id='vukC3'><q id='vukC3'><span id='vukC3'><b id='vukC3'><form id='vukC3'><ins id='vukC3'></ins><ul id='vukC3'></ul><sub id='vukC3'></sub></form><legend id='vukC3'></legend><bdo id='vukC3'><pre id='vukC3'><center id='vukC3'></center></pre></bdo></b><th id='vukC3'></th></span></q></dt></tr></i><div id='vukC3'><tfoot id='vukC3'></tfoot><dl id='vukC3'><fieldset id='vukC3'></fieldset></dl></div>

          <bdo id='vukC3'></bdo><ul id='vukC3'></ul>

                  <tbody id='vukC3'></tbody>

                • <small id='vukC3'></small><noframes id='vukC3'>

                • 本文介绍了在单独的线程中运行异步循环,信号来自和循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  我正在尝试制作一个在后台与多个 BLE 设备进行通信的 UI.为此,我实现了一个运行 asyncio.loop 的单独线程.这是必要的,因为我使用 bleak 0.9.1 连接到设备.

                  I'm trying to make a UI which communicates in the background with several BLE devices. For that I've implemented a separate thread which runs an asyncio.loop. This is necessary because I use bleak 0.9.1 to connect to the devices.

                  使用信号和槽将数据从 UI 线程获取到工作线程可以正常工作.但是,它在另一个方向上不起作用.据我所知,这是因为线程忙于运行循环并且永远不会停止这样做.因此,它无法处理来自 UI 线程的输入.

                  Using signals and slots to get data from the UI-thread to the worker thread works fine. However, it does not work in the other direction. As far as I know this is because the thread is busy running the loop and never stops doing that. Therefore, it cannot process the inputs from the UI-thread.

                  下面有一个显示问题的示例代码.

                  Below there is an example code which shows the problem.

                  有什么方法可以在运行 asyncio 循环的同时处理线程中的输入槽?

                  Is there any way to process the input slots in the thread while running the asyncio loop?

                  import sys
                  from PyQt5.QtWidgets import QWidget, QPushButton, QApplication, QVBoxLayout
                  from PyQt5.QtCore import QThread, QObject, pyqtSignal, pyqtSlot
                  import asyncio
                  
                  class Test_Thread(QObject):
                      signal_back = pyqtSignal(int)
                  
                      def __init__(self,
                                   loop: asyncio.AbstractEventLoop,
                                   parent=None):
                          super(Test_Thread, self).__init__(parent)
                          self.text = "Task1 not configured"
                          self.loop = loop
                          self.counter = 0
                  
                      @pyqtSlot(str)
                      def set_text_slot(self, txt):
                          self.text = txt
                  
                      async def do_stuff1(self):
                          while True:
                              print(self.text)
                              await asyncio.sleep(2.0)
                  
                      async def do_stuff2(self):
                          while True:
                              self.counter += 1
                              self.signal_back.emit(self.counter)
                              await asyncio.sleep(1.0)
                  
                      def work(self):
                          #run the event loop
                          try:
                              asyncio.ensure_future(self.do_stuff1(), loop=self.loop)
                              asyncio.ensure_future(self.do_stuff2(), loop=self.loop)
                              self.loop.run_forever()
                          finally:
                              print("Disconnect...")
                  
                  
                  class Window(QWidget):
                  
                      set_text_signal = pyqtSignal(str)
                  
                      def __init__(self, parent=None):
                          super(Window, self).__init__()
                          self.initUi()
                          self.startThread()
                  
                      def initUi(self):
                          layout = QVBoxLayout()
                          self.button = QPushButton('User input')
                          self.button.clicked.connect(self.sendtotask)
                          layout.addWidget(self.button)
                          self.setLayout(layout)
                          self.show()
                  
                      def startThread(self):
                          loop = asyncio.get_event_loop()
                          self.asyciothread = Test_Thread(loop)
                          self.thread = QThread()
                          self.asyciothread.moveToThread(self.thread)
                  
                          self.set_text_signal.connect(self.asyciothread.set_text_slot)
                          self.asyciothread.signal_back.connect(self.receivefromthread)
                          self.thread.started.connect(self.asyciothread.work)
                  
                          self.thread.start()
                  
                      @pyqtSlot(int)
                      def receivefromthread(self, number):
                          print(str(number))
                  
                      def sendtotask(self):
                          self.set_text_signal.emit("Task: Configured")
                  
                  
                  if __name__ == "__main__":
                      app = QApplication(sys.argv)
                      ui = Window()
                      ui.show()
                      sys.exit(app.exec_())
                  

                  推荐答案

                  Qt 不需要使用线程来使用 asyncio,因为有 asyncqtqasync 启用它:

                  It is not necessary to use threads to use asyncio with Qt since there are libraries like asyncqt and qasync that enable it:

                  import asyncio
                  import sys
                  
                  from PyQt5.QtWidgets import QWidget, QPushButton, QApplication, QVBoxLayout
                  from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot
                  
                  from asyncqt import QEventLoop
                  # from qasync import QEventLoop
                  
                  
                  class Worker(QObject):
                      signal_back = pyqtSignal(int)
                  
                      def __init__(self, loop: asyncio.AbstractEventLoop, parent=None):
                          super(Worker, self).__init__(parent)
                          self.text = "Task1 not configured"
                          self.loop = loop
                          self.counter = 0
                  
                      @pyqtSlot(str)
                      def set_text_slot(self, txt):
                          self.text = txt
                  
                      async def do_stuff1(self):
                          while True:
                              print(self.text)
                              await asyncio.sleep(2.0)
                  
                      async def do_stuff2(self):
                          while True:
                              self.counter += 1
                              self.signal_back.emit(self.counter)
                              await asyncio.sleep(1.0)
                  
                      def work(self):
                          asyncio.ensure_future(self.do_stuff1(), loop=self.loop)
                          asyncio.ensure_future(self.do_stuff2(), loop=self.loop)
                  
                  
                  class Window(QWidget):
                      set_text_signal = pyqtSignal(str)
                  
                      def __init__(self, parent=None):
                          super(Window, self).__init__()
                          self.initUi()
                          self.start_task()
                  
                      def initUi(self):
                          layout = QVBoxLayout(self)
                          self.button = QPushButton("User input")
                          self.button.clicked.connect(self.sendtotask)
                          layout.addWidget(self.button)
                  
                      def start_task(self):
                          loop = asyncio.get_event_loop()
                          self.worker = Worker(loop)
                          self.set_text_signal.connect(self.worker.set_text_slot)
                          self.worker.signal_back.connect(self.receive_from_worker)
                          self.worker.work()
                  
                      @pyqtSlot(int)
                      def receive_from_worker(self, number):
                          print(str(number))
                  
                      def sendtotask(self):
                          self.set_text_signal.emit("Task: Configured")
                  
                  
                  if __name__ == "__main__":
                      app = QApplication(sys.argv)
                      loop = QEventLoop(app)
                      asyncio.set_event_loop(loop)
                      ui = Window()
                      ui.show()
                      with loop:
                          loop.run_forever()
                  

                  这篇关于在单独的线程中运行异步循环,信号来自和循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  上一篇:使用按键单击时如何更改pyqt5中的按钮文本 下一篇:从 Singleton 接收 pyqtSignal

                  相关文章

                  最新文章

                • <legend id='mpXcx'><style id='mpXcx'><dir id='mpXcx'><q id='mpXcx'></q></dir></style></legend>

                      <bdo id='mpXcx'></bdo><ul id='mpXcx'></ul>

                    <tfoot id='mpXcx'></tfoot>

                    1. <i id='mpXcx'><tr id='mpXcx'><dt id='mpXcx'><q id='mpXcx'><span id='mpXcx'><b id='mpXcx'><form id='mpXcx'><ins id='mpXcx'></ins><ul id='mpXcx'></ul><sub id='mpXcx'></sub></form><legend id='mpXcx'></legend><bdo id='mpXcx'><pre id='mpXcx'><center id='mpXcx'></center></pre></bdo></b><th id='mpXcx'></th></span></q></dt></tr></i><div id='mpXcx'><tfoot id='mpXcx'></tfoot><dl id='mpXcx'><fieldset id='mpXcx'></fieldset></dl></div>

                      <small id='mpXcx'></small><noframes id='mpXcx'>