暂停Jupyter Notebook小部件,等待用户输入

时间:2019-03-19 15:42:55

标签: python button widget jupyter-notebook ipywidgets

我和TheInterestedOne asked有相同的问题。我需要为用户创建两个按钮,并建议用户在循环中单击两个按钮之一,以便仅在用户选择后才进行循环的下一次迭代。我读了this source,但不能使它适用于按钮。我不明白,在使用按钮的情况下小部件属性会如何变化。

git clone https://github.com/Azrael3000/tmpi.git

谢谢。

3 个答案:

答案 0 :(得分:2)

要具有多个按钮,您可以将其他小部件添加到@IanMulvany的先前答案之一。

有关以下内容与以前的答案的不同之处,请参见下面的代码中的--------。

from ipywidgets import Button, HBox #<----- Add HBox for displaying multiple buttons
import asyncio

def wait_for_change(widget1, widget2): #<------ Rename to widget1, and add widget2
    future = asyncio.Future()
    def getvalue(change):
        future.set_result(change.description)
        widget1.on_click(getvalue, remove=True) #<------ Rename to widget1
        widget2.on_click(getvalue, remove=True) #<------ New widget2
        # we need to free up the binding to getvalue to avoid an IvalidState error
        # buttons don't support unobserve
        # so use `remove=True` 
    widget1.on_click(getvalue) #<------ Rename to widget1
    widget2.on_click(getvalue) #<------ New widget2
    return future

button1=Button(description="wow") #<------ Rename to button1
button2=Button(description="wow2") #<------ New button2 and description

list_to_tag = ["one", "two", "three", "four"]

async def f():
    for i in list_to_tag:
        print('going to tag ', i)
        x = await wait_for_change(button1,button2) #<---- Pass both buttons into the function
        if x == "wow": #<--- use if statement to trigger different events for the two buttons
            print("tagged ", i, "with  %s"%x)
        else:
            print(i, "tagged with %s"%x)
        print("")
        print("")

asyncio.create_task(f())
HBox([button1,button2]) #<----Display both buttons in an HBox

答案 1 :(得分:0)

以下是适用于Button的示例。主要更改是在修饰器中,将observe换成on_click,这在按钮上相当于观察到的情况。

from functools import wraps
def yield_for_change(widget):
    def f(iterator):
        @wraps(iterator)
        def inner():
            i = iterator()
            def next_i(change):
                try:
                    i.send(change)
                except StopIteration as e:
                    widget.unobserve(next_i, attribute)
            widget.on_click(next_i)
            # start the generator
            next(i)
        return inner
    return f


from ipywidgets import Button
button=Button()

def on_button_clicked():
    print("Button clicked.")


@yield_for_change(button)
def f():
    for i in range(10):
        print('did work %s'%i)
        x = yield

f()

button

答案 2 :(得分:0)

此版本使用awaitio,并为按钮进行了修改。

from ipywidgets import Button
import asyncio

def wait_for_change(widget):
    future = asyncio.Future()
    def getvalue(change):
        future.set_result(change.description)
        widget.on_click(getvalue, remove=True) 
        # we need to free up the binding to getvalue to avoid an IvalidState error
        # buttons don't support unobserve
        # so use `remove=True` 
    widget.on_click(getvalue)
    return future

button=Button(description="wow")

list_to_tag = ["one", "two", "three", "four"]

async def f():
    for i in list_to_tag:
        print('going to tag ', i)
        x = await wait_for_change(button)
        print("tagged ", i, "with  %s"%x)
        print("")

asyncio.create_task(f())
button