散景,无法将事件绑定到小部件

时间:2019-01-28 16:24:27

标签: python bokeh

这是我第一次使用bokeh。我正在使用Windows 7,Pycharm作为IDE和python 3.7。我正在尝试使用4 TextInput制作一个表单,以从用户那里获取均值,方差,行数和列数的值,并带有一个Button,当单击该按钮时会生成具有正态分布的随机数的数据框,其中输入均值和方差定义的输入大小。我按照adding widgets link制作了表格,并编写了数据框生成器。但是我很难将其绑定到按钮。为了确保正确处理该事件,我添加了另一个TextInput只是为了在单击按钮时显示均值TextInput的值。代码如下:

from bokeh.models.widgets import TextInput, Button, Div
from bokeh.layouts import layout, column, row
from bokeh.io import curdoc ## to assign callback to widget

from bokeh import events    ## for event handling
from bokeh.models import CustomJS

import numpy as np
import pandas as pd

text_input_mean = TextInput(value="0.0", title="Enter mean:")
text_input_vaiance = TextInput(value="0.0", title="Enter variance:")
text_input_rows = TextInput(value="5", title="Enter num rows:")
text_input_columns = TextInput(value="5", title="Enter num columns:")

button = Button(label = "Generate Dataframe", button_type = "success")

text_output = TextInput(title = 'Python result is shown here: ')

div = Div(text="""Making a form with bokeh mainly to handle events.""",
width=500, height=50)

layout = column(div, row(text_input_mean, text_input_vaiance), row(text_input_rows, text_input_columns),
                button, text_output)
show(layout)

## Events with no attributes
# button.js_on_event(events.ButtonClick, button_click_handler) # Button click

def my_text_input_handler(attr, old, new):
    print("Previous label: " + old)
    print("Updated label: " + new)
text_input_mean.on_change("value", my_text_input_handler)

def button_click_handler():
    text_output.__setattr__('value', str(text_input_mean.value))
    #text_output.value = str(text_input_mean.value)



button.on_click(button_click_handler)
# button.on_click(generate_normal_df)
# curdoc().add_root(layout)

def generate_normal_df(mean, var, x, y):
    mean = text_input_mean.value
    variance = text_input_vaiance.value
    row_num = x
    col_num = y
    return pd.DataFrame(np.random.normal(loc = mean, scale = variance, size=(row_num, col_num)))

该表单如下所示:enter image description here

单击按钮后,什么也不会发生!我也查看了控制台,但是也没有。我在同一链接中使用了方法“ my_text_input_handler”,以查看是否更改了text_input_mean的值,但是还是没有变化。我尝试了另一种方法来遵循此link,这就是为什么您可以在我的代码中看到它的原因:

button.on_click(generate_normal_df)
curdoc().add_root(layout)

我稍后会评论。但是当我使用这两行代码时,出现以下错误:

enter image description here

也是这一行:

button.on_click(button_click_handler)

在我的IDE中引起另一个错误。当我使用button_click_handler()时,出现以下错误:

_attach_document中的第609行“ C:\ Users \ E17538 \ anaconda3 \ lib \ site-packages \ bokeh \ model.py”     引发RuntimeError(“模型必须仅由单个文档拥有,%r已在文档中”%(self)) RuntimeError:模型必须仅由一个文档拥有,WidgetBox(id ='1009',...)已存在于文档中

当我不带()使用它时,我再次遇到相同的错误。如果您能指导我如何将处理程序绑定到我的小部件,我将不胜感激。非常感谢。

1 个答案:

答案 0 :(得分:1)

您的代码有一些问题。第一个是通常不应同时使用showcurdoc().add_root(...)show函数用于显示独立 Bokeh内容,即仅显示静态HTML和JS,而没有Bokeh服务器。但是,curdoc().add_root通常在Bokeh服务器应用程序的上下文中使用。这两个函数都将它们的值相加,然后传递给新的Bokeh Document,这是错误的直接原因(模型只能属于一个Document,而您已经将它们添加到了两个)。在这种情况下,正确的解决方法是删除对show的调用。

此外,on_click还希望有一个回调函数,该函数需要零个必需参数。但是,您正在传递generate_normal_df,它具有四个必需的位置参数。这是行不通的(单击按钮时,Bokeh无法知道要传递哪些参数)。如果要使用generate_normal_df,则需要用lambda进行包装,或使用functools.partial来烘焙一些固定的参数值,然后传递结果。