Я пытаюсь инициализировать значение параметра функции, которое иначе контролируется через виджет. Я хочу сделать это при первом вызове этой функции и впоследствии отвечать на вводимые пользователем данные.
Например:
import ipywidgets as widgets
init = True
def test(a):
global init
if init:
a = 0.5 # would in practice need some processing
init = False
print(a)
widgets.interact(test, a = (0,2,.1))
Я знаю, как установить начальное значение виджета, установив параметр функции в определении:
import ipywidgets as widgets
init = True
def test(a=0.5):
print(a)
widgets.interact(test, a = (0,2,.1))
но это не то, чего я пытаюсь достичь.
Наивный первый пример выше не делает то, что я хочу, но мне интересно, возможно ли вообще то, чего я пытаюсь достичь, концептуально. Ведь виджет - это не "индикатор", а "управление"... Другими словами, есть ли способ «переговорить» с виджетом и обновить его значение изнутри функции, которой он управляет?
Что я хотел сказать о первом примере, так это то, что, хотя он и устанавливает значение «a» равным 0,5 (что подтверждается оператором печати), ползунок остается заблокированным на медианном значении между 0 и 2, то есть 1. Я ищу способ обновить ползунок, чтобы он отражал начальное значение 0,5 (опять же, это начальное значение будет вычислено, поэтому его нельзя установить априори, как это сделано в примере 2). И нет, я не настроен использовать Interact().
Думаю, я получил то, что тебе нужно сейчас. Я предлагаю два подхода, один из которых ближе к тому, что показано в документации, возможно, является немного более простым вариантом. Тем не менее, возможно, это не подходит для вашего использования, и поэтому существует подход, который больше соответствует первоначальной установке значения ползунка внутри функции.
Придерживаясь interact()
, вы можете передать виджет, чтобы указать параметры, такие как начальное значение ползунка, как описано здесь и в документации ipywidgets для взаимодействия(), где это указано interact(f, x=widgets.IntSlider(min=-10, max=30, step=1, value=10));
. Просто добавьте этот подход в свой фрагмент кода:
import ipywidgets as widgets
init = 0.5
def test(a):
print(a)
widgets.interact(test, a = widgets.FloatSlider(min=0, max=2, step=0.1, value=init));
Это начнется с 0,5, а не с середины диапазона ползунка.
Это выше приближает к документации; однако на самом деле вы также можете установить начальное значение внутри функции.
В этом примере я придерживаюсь вашего кода и не устанавливаю начальное значение в ползунке, но выполняю настройку внутри функции по вашему запросу. Ключом является доступ и установка атрибута value
ползунка после назначения ему дескриптора, например:
import ipywidgets as widgets
init = True
slider = widgets.FloatSlider(min=0, max=2, step=0.1)
def test(a):
global init
if init:
slider.value = 0.5
init = False
print(a)
widgets.interact(test, a = slider)
Объединение вашего кода с моделированием ситуации, когда значение вначале определяется чем-то другим (априори не зная значения) здесь, где я выбираю случайное число в начале, дает следующее:
from ipywidgets import interact
import ipywidgets as widgets
import random
max_secret = 10
secret = random.randint(1, max_secret)
slider = widgets.IntSlider(
value=secret,
min=0,
max= max_secret,
step=1,
description='Choose value:',
disabled=False,
continuous_update=False,
orientation='horizontal',
style= {'description_width': 'initial'},
readout=True,
readout_format='d'
)
def test_func(x):
output.update(f"The current value is: {slider.value} That value times 5 is {slider.value * 5}")
output = display(f"The starting value is: {slider.value}", display_id=True)
interact(test_func, x=slider);
И вариант этого подхода, более близкий к версии, где значение ползунка устанавливается в функции, указанной в заголовке:
from ipywidgets import interact
import ipywidgets as widgets
import random
max_secret = 10
secret = random.randint(1, max_secret)
init = True
slider = widgets.IntSlider(
min=0,
max= max_secret,
step=1,
description='Choose value:',
disabled=False,
continuous_update=False,
orientation='horizontal',
style= {'description_width': 'initial'},
readout=True,
readout_format='d'
)
def test_func(x):
global init
if init:
slider.value = secret
init = False
output.update(f"The current value is: {slider.value} That value times 5 is {slider.value * 5}")
output = display(f"The starting value is: {secret}", display_id=True)
interact(test_func, x=slider);
Замечательно. Спасибо, что нашли время написать это. Я определенно многому научился.
Вы готовы использовать
interact()
? Я думаю, вы могли бы использовать ползунок с настройкой значения, а затем использоватьon_value_change(change)
для управления им через свою функцию. Я думаю. Я не совсем понимаю, что вы имеете в виду после первоначальной настройки?