添加一个没有JavaScript的自定义python散景小部件

时间:2017-02-02 07:16:28

标签: python widget bokeh

我想在不使用JavaScript的情况下创建自定义散景窗口小部件,即不遵循Adding A Custom Widget上的散景文档。下面的例子演示了如何在PyQt4中创建一个自定义小部件(我经常使用它),以及我期望在散景中工作以及我得到的错误消息。

还有其他方法可以在不使用JavaScript的情况下在散景中创建自定义小部件吗?具体来说,我试图创建一个自定义滑块,每侧有小 - 和+按钮,将滑块递增/递减1步。我想在许多应用程序中使用这个自定义小部件,所以我希望它定义为自己的类,其中on_change方法链接到滑块on_change方法。我想制作散景中的其他自定义小部件(没有JS!),我想知道这是否可能。

# this works as a base to develop custom PyQt4 widgets
from PyQt4 import QtGui
import sys

class NewWidget(QtGui.QWidget):
    def __init__(self):
        super().__init__()

app = QtGui.QApplication([])
widget = NewWidget()
widget.show()
sys.exit(app.exec_())


# this does not work as a base to develop custom bokeh widgets
# when run, a tab opens with the message
# Bokeh Error
# Model `NewWidget' does not exist. This could be due to a widget
# or a custom model not being registered before first usage.
from bokeh.plotting import show
from bokeh.layouts import widgetbox
from bokeh.models.widgets import Widget

class NewWidget(Widget):
    def __init__(self):
        super().__init__()

new = NewWidget()
show(widgetbox(new))

更新:我试图创建的特定自定义小部件是一个滑块,每侧有一个按钮(左侧标有' - ',右侧标有'+'),将Slider值更改为1步。这用于微调Slider的值,因此鼠标不需要精确地达到目标值。我通过链接默认的Slider和Button对象创建了这个自定义小部件,它在浏览器中呈现,但回调功能不起作用(特别是Slider'on_change'方法)。

Slider With Buttons

这个自定义小部件是否可以直接用bokeh和JS实现?是否有一个在线参考可以提供提示,而不会深入JS。

1 个答案:

答案 0 :(得分:3)

Bokeh是一个用于在现代浏览器(或嵌入式HTML小部件)中生成绘图和可视化应用程序的库。它由两个基本部分组成。 Bokeh的python方面实际上只是一个复杂的“包装器”或“绑定”,最终产生一个声明性的JSON文档,它反过来驱动一个实际完成浏览器中所有工作的JavaScript库(BokehJS)。

扩展Bokeh必然意味着提供该等式的两个方面:您必须提供扩展的(通常非常小的)python声明,它实际上只是指定自动生成上述JSON格式所需的信息。而且你还必须为扩展提供JavaScript(或Cof​​feeScript)实现,它实际上完成了浏览器中的所有工作。

由于浏览器无法运行Python代码,因此实现必须是JavaScript

有一些库,如Flexx和Brython,可以将python“转换”为JavaScript。您可能会发现它们有助于避免直接编写JavaScript,但这些库在某些用例中经常会出现怪癖和特定缺陷,因此YMMV。

以下是一个完整的示例,它使用按钮上的CustomJS回调来更新滑块:

from bokeh.models import Button, CustomJS, Slider
from bokeh.layouts import row
from bokeh.io import output_file, show

slider = Slider(start=0, end=10, value=0, step=0.1)

button = Button()
button.callback = CustomJS(args=dict(slider=slider), code="""
    slider.value += 0.1
""")

output_file("foo.html")

show(row(slider, button))