Как запустить и остановить цикл с интерактивным флажком ipywidget? - PullRequest
0 голосов
/ 12 июня 2019

Я пытаюсь запустить и остановить цикл с помощью простого флажка.Но я не знаю, как я могу обновить состояние флажка в цикле while.

Ниже вы можете увидеть, что у меня есть, но когда я снимаю флажок, цикл while не распознает его.,

Я искал интерактивные функции, но не нашел ни одной функции для получения обновленного состояния флажка.

Надеюсь, вы, ребята, можете мне помочь:)

import ipywidgets
import time

def f(x):
    while x==True:
        print("!")
        time.sleep(1)

c=ipywidgets.interactive(f,x=False)
c

1 Ответ

0 голосов
/ 13 июня 2019

Если вы установите флажок явно с помощью:

checkbox = widgets.Checkbox(description='click me')

... вы можете получить текущее значение с помощью checkbox.value.

Досадно, что этого недостаточно, чтобы позволить вашему флажку остановить выполнение цикла while. После запуска цикла while он занимает интерпретатор Python. Следовательно, нет места для интерпретации изменений флажка до завершения цикла while.

Поскольку это принципиально проблема параллелизма (вы хотите реагировать на изменения в флажке во время выполнения вычислений), вам нужно использовать примитивы параллелизма Python. Например, вы можете достичь этого с помощью сопрограмм :

import ipywidgets as widgets
import asyncio


class HaltableExecutor:

    def __init__(self, checkbox):
        self._checkbox = checkbox

    async def my_code(self):
        # This is your user code
        while True:
            if self._checkbox.value:
                print('running')  # put your code here
            await asyncio.sleep(0.1)  # use this to temporarily give up control of the event loop to allow scheduling checkbox changes

    def start(self):
        print('starting')
        asyncio.ensure_future(self.my_code())

Затем создайте и отобразите свой флажок:

c = widgets.Checkbox(description='click me')
c

... и запустите вашего исполнителя:

exe = HaltableExecutor(c)
exe.start()

Теперь будет выполняться цикл while. На каждой итерации мы делаем паузу, чтобы отказаться от управления циклом событий с помощью asyncio.sleep. Количество, на которое мы спим, не имеет значения, дело в том, чтобы вернуть контроль. Это дает основному потоку возможность иметь дело с выдающимися сообщениями, такими как изменения флажков. На следующей итерации цикла while снова проверяется self._checkbox.value и т. Д.

...