首页 > 解决方案 > 关闭一个while循环以在pyqt5中启动另一个循环,并在python和asyncio中单击按钮

问题描述

我正在尝试编写一个python脚本,该脚本在单击button1后使用asyncio启动一个线程,然后再次单击button2,它会关闭thread1并使用不同的参数启动另一个循环。

这是我想做的一种方式,但是创建线程2时线程1不会停止...

请问你能帮帮我吗?

import os
import sys
import quamash
import asyncio
import traceback
import PyQt5
import pdb
import math


# Required setup to get event loop working
app = PyQt5.QtWidgets.QApplication(sys.argv)
loop = quamash.QEventLoop(app)
asyncio.set_event_loop(loop)
loop.set_debug(True)  # optional


# Select QT5
# https://github.com/enthought/traitsui/issues/407
os.environ["ETS_TOOLKIT"] = "qt"
os.environ["QT_API"] = "pyqt5"
from traits.api import HasTraits, Button, Instance, Int, Bool
from traitsui.api import ModelView, View, Item, Label
from PyQt5.QtCore import pyqtRemoveInputHook

pyqtRemoveInputHook()  # enabled pdb.set_trace()    ????


class App(HasTraits):
    """ Traits application model.
    """

    running = Bool(False)

    async def test_task(self):



        while True:  
       
           loop = asyncio.get_event_loop()
           self.running = True
           print("oooooooooooook")   #commande pour faire actioer position et retour indfo console 
           await asyncio.sleep(0.02, loop)
           self.running = False


    running = Bool(False)

    async def test_task2(self):


        while True:
               
           loop = asyncio.get_event_loop()
           self.running = True
           print("ko")   #commande pour faire actioer position et retour indfo console 
           await asyncio.sleep(0.02, loop)

           self.running = False

class AppView(ModelView):
    """ Traits application view.
    """

    model = Instance(App)

    test_task_btn = Button("START1")
    test_task_btn2 = Button("STOP1andSTART2")
    def close(self, info, is_ok):
        print("Close")
        return True

    def _test_task_btn_fired(self):
        print("Button pressed.")
        try:
            loop.close 
            loop.create_task(self.model.test_task())
        except:
            traceback.print_exc()
            print("Problem")

    def close(self, info, is_ok):
        print("Close")
        return True

    def _test_task_btn2_fired(self):
        print("Button2 pressed.")
        try:
            loop.close
            loop.create_task(self.model.test_task2())
        except:
            traceback.print_exc()
            print("Problem")

    def default_traits_view(self):
        view = View(
            Label("TesterLite"),
            Item("test_task_btn", show_label=False ),
            Item("test_task_btn2", show_label=False),            
            resizable=True,
            title="MoteusControllerTesterLite",
            height=400,
            width=400,

        )
        return view

with loop:
    print("Launching app.")
    model = App()
    view = AppView(model=model)
    view.edit_traits()
    print("edit_traits")
    if sys.version_info[0] == 3 and sys.version_info[1] >= 8:
        asyncio.events._set_running_loop(loop)  # Need if using >= Python 3.8


    loop.run_forever()


    print("Finished run_forever()")
print("App closed.")

标签: pythonpyqt5python-asyncio

解决方案


您必须使用一个用于终止 while 的标志:

async def test_task(self, event):
    while not event.is_set():
        loop = asyncio.get_event_loop()
        print("ok")
        await asyncio.sleep(0.02, loop)
class AppView(ModelView):
    """Traits application view."""

    model = Instance(App)

    test_task_btn = Button("START1")
    test_task_btn2 = Button("STOP1andSTART2")

    event = asyncio.Event()

    def _test_task_btn_fired(self):
        print("Button pressed.")
        try:
            loop.create_task(self.model.test_task(self.event))
        except:
            traceback.print_exc()
            print("Problem")

    def _test_task_btn2_fired(self):
        print("Button2 pressed.")
        self.event.set()
        try:
            loop.create_task(self.model.test_task2())
        except:
            traceback.print_exc()
            print("Problem")

    def default_traits_view(self):
        view = View(
            Label("TesterLite"),
            Item("test_task_btn", show_label=False),
            Item("test_task_btn2", show_label=False),
            resizable=True,
            title="MoteusControllerTesterLite",
            height=400,
            width=400,
        )
        return view

推荐阅读