2016-03-03 55 views
3

我對python和python筆記本很新穎。我試圖創建一個Jupyter筆記本,它將顯示圖像列表中的圖像,併爲用戶提供4個可選擇的可點擊ipywidget按鈕中的圖像的選項。一旦用戶點擊他們的選擇,我想用新圖像替換圖像,並用4個新選項重新填充按鈕。使用ipywidget進行多項選擇測試

我知道如何清除圖像輸出並使用button.close()關閉按鈕小部件,但我似乎無法弄清楚如何重新繪製帶有新選項的按鈕。一旦我關閉了容器,我無法弄清楚如何循環返回頂部,因爲一旦做出選擇,我就會陷入on_button_clicked函數中。這是迄今爲止我所知道的,儘管我知道它沒有接近工作的地方,而且在這種方法中可能會失敗。注意:我並不需要使用ipywidgets,但它似乎是一個不錯的選擇可點擊按鈕的意義:

x = ['tree.jpg','house.jpg','car.jpg','door.jpg','train.jpg','moon.jpg'] 

choices = random.sample(x, 4) 
correct = random.choice(choices) 

display(Image(correct)) 
time.sleep(3) 

button1 = widgets.Button(description = x[0]) 
button2 = widgets.Button(description = x[1]) 
button3 = widgets.Button(description = x[2]) 
button4 = widgets.Button(description = x[3]) 

container = widgets.HBox(children=[button1,button2,button3,button4]) 
display(container) 


button1.on_click(on_button1_clicked) 
button2.on_click(on_button2_clicked) 
button3.on_click(on_button3_clicked) 
button4.on_click(on_button4_clicked) 


def on_button1_clicked(b): 
    # [insert code to record choice] 
    container.close() 
    clear_output() 

def on_button2_clicked(b): 
    # [insert code to record choice] 
    container.close() 
    clear_output() 

def on_button3_clicked(b): 
    # [insert code to record choice] 
    container.close() 
    clear_output() 

def on_button4_clicked(b): 
    # [insert code to record choice] 
    container.close() 
    clear_output() 

非常感謝!

+0

你應該包括你的import語句也!你有沒有考慮過使用'while'循環,在條件滿足後''break's? – nluigi

回答

4

如果我知道你想做什麼,你可以把一切都變成一個獨立的功能,並有一個稱爲每次一個按鈕被點擊:

import random 
import time 
from IPython.display import Image, display, clear_output 
from ipywidgets import widgets 

x = ['tree.jpg','house.jpg','car.jpg','door.jpg','train.jpg','moon.jpg'] 

def redraw(): 
    choices = random.sample(x, 4) 
    correct = random.choice(choices) 

    display(Image(correct)) 
    time.sleep(3) 

    button1 = widgets.Button(description = choices[0]) 
    button2 = widgets.Button(description = choices[1]) 
    button3 = widgets.Button(description = choices[2]) 
    button4 = widgets.Button(description = choices[3]) 

    container = widgets.HBox(children=[button1,button2,button3,button4]) 
    display(container) 

    def on_button1_clicked(b): 
     # [insert code to record choice] 
     container.close() 
     clear_output() 
     redraw() 

    def on_button2_clicked(b): 
     # [insert code to record choice] 
     container.close() 
     clear_output() 
     redraw() 

    def on_button3_clicked(b): 
     # [insert code to record choice] 
     container.close() 
     clear_output() 
     redraw() 

    def on_button4_clicked(b): 
     # [insert code to record choice] 
     container.close() 
     clear_output() 
     redraw() 

    button1.on_click(on_button1_clicked) 
    button2.on_click(on_button2_clicked) 
    button3.on_click(on_button3_clicked) 
    button4.on_click(on_button4_clicked) 

redraw() # initializes the first choice 

一些評論:

  • 我想,在你想從4的樣本中選擇 文本的 文本的描述中,您選擇了choices而不是 列表x的前四個元素(因爲這些元素沒有變化)。
  • 您可能不想將選項的數量硬編碼爲4,因爲您硬編碼了4個按鈕和4個按鈕功能等。您可能希望根據所需選項的數量生成一個按鈕列表。喜歡的東西:

    nchoices = 4 
    x = ['tree.jpg','house.jpg','car.jpg','door.jpg','train.jpg','moon.jpg'] 
    
    def redraw():  
        choices = random.sample(x, nchoices) 
        correct = random.choice(choices) 
    
        display(Image(correct)) 
        time.sleep(3) 
    
        buttons = [widgets.Button(description = choice) for choice in choices] 
    
        container = widgets.HBox(children=buttons) 
        display(container) 
    
        def on_button_clicked(b): 
         # [insert code to record choice] 
         container.close() 
         clear_output() 
         redraw() 
    
        for button in buttons: 
         button.on_click(on_button_clicked) 
    
    redraw() 
    

    節省約一半的代碼。

  • 我不知道你想要做什麼,通過點擊一個按鈕,但我可以想象你想比較choicecorrect,然後用這些信息做些事情。你可以做的比較簡單的b.description == correct和建議做什麼,然後對顏色的按鈕'green'如果條件True'red'否則像這樣:

    def on_button_clicked(b): 
        choice = b.description 
        b.color = 'white' 
        b.background_color = 'green' if choice == correct else 'red' 
        time.sleep(5) 
        container.close() 
        clear_output() 
        redraw() 
    
+0

工作就像一個魅力!非常感謝!我不知道像on_button_clicked(b)這樣的函數內部的函數可以調用父函數redraw()。這是非常有用的理解。 – Snapula

+0

@Snapula - 不客氣!這是一種[遞歸](http://openbookproject.net/thinkcs/python/english3e/recursion.html),它適用於這種情況。確實非常有用:) – nluigi