gpt4 book ai didi

python - 我可以强制我的启用容器从 Traitsui 处理程序重绘吗?

转载 作者:行者123 更新时间:2023-11-30 23:17:22 26 4
gpt4 key购买 nike

我使用了 traitsui.api.Handler 来捕获和处理 traitsui.api.View 的事件,该 View 包含一个按钮,其行为是删除来自包含多个绘图的容器的绘图。当使用 remove 按钮、调用 pop() 方法并删除绘图时,将访问容器的组件列表。但是, View 不会重绘,因此该图似乎保留在原处。通过拖动一个角来调整窗口大小将强制重绘,确认 pop()

问题是:如何以编程方式强制重绘?

在我看来,这样做的正确位置是在处理程序的 setattr 方法中,就在 pop()-ing 绘图之后。

# Major library imports

from numpy import linspace
from scipy.special import jn

# Enthought library imports
from enable.api import Container, ComponentEditor
from traits.api import HasTraits, Instance, Button, Int, Str
from traitsui.api import Item, HGroup, View, VSplit, UItem, InstanceEditor, Handler

# Chaco imports
from chaco.api import ArrayPlotData, GridContainer, Plot

# ===============================================================================
# Attributes to use for the plot view.
size = (1000, 800)

COLOR_PALETTE = [
(0.65098039, 0.80784314, 0.89019608, 1.0),
(0.12156863, 0.47058824, 0.70588235, 1.0),
(0.69803922, 0.8745098, 0.54117647, 1.0),
(0.2, 0.62745098, 0.17254902, 1.0),
(0.98431373, 0.60392157, 0.6, 1.0),
(0.89019608, 0.10196078, 0.10980392, 1.0),
(0.99215686, 0.74901961, 0.43529412, 1.0),
(1., 0.49803922, 0., 1.0),
(0.79215686, 0.69803922, 0.83921569, 1.0),
]


class InstanceUItem(UItem):
"""Convenience class for including an Instance in a View"""
style = Str('custom')
editor = Instance(InstanceEditor, ())



# ===============================================================================
# # ManagerHandler will be the View's handler
#===============================================================================
class ManagerHandler(Handler):
def setattr(self, info, object, name, value):
Handler.setattr(self, info, object, name, value)
info.ui.context['pgrid'].plots_container.components.pop()
#At this point, the container does not redraw, and so, while it no longer
#contains the last plot in its components collection, that plot is still
# visible

# ===============================================================================
# # PlotsGrid class that is used by the demo
#===============================================================================
class PlotsGrid(HasTraits):
plots_container = Instance(Container)
rows = Int(3)
cols = Int(3)

#===============================================================================
# # Create the plots, this is adapted from the chaco GridContainer demo
#===============================================================================
def _plots_container_default(self):
# Create a GridContainer to hold all of our plots
container = GridContainer(padding=20, fill_padding=True,
bgcolor="lightgray", use_backbuffer=True,
shape=(self.rows, self.cols), spacing=(20, 20))

# Create the initial series of data
x = linspace(-5, 15.0, 100)
pd = ArrayPlotData(index=x)

# Plot some bessel functions and add the plots to our container
for i in range(self.rows * self.cols):
pd.set_data("y" + str(i), jn(i, x))
plot = Plot(pd)
plot.plot(("index", "y" + str(i)),
color=tuple(COLOR_PALETTE[i]), line_width=2.0,
bgcolor="white", border_visible=True)

container.add(plot)
return container



# ===============================================================================
# # Controls HasTraits provides a button used to wire in the desired behavior
#===============================================================================
class Controls(HasTraits):
rem_plot = Button("remove ...")

def _rem_plot_changed(self):
print "rem plot changed"



# ===============================================================================
# # manager_view provides the View and defines its layout
#===============================================================================
manager_view = View(
VSplit(
HGroup(
Item('controls.rem_plot', height=32)
),
Item('pgrid.plots_container', editor=ComponentEditor(size=size), show_label=False),
show_border=True
),
handler=ManagerHandler(),
resizable=True
)

grid = PlotsGrid()
ctrl = Controls()

if __name__ == "__main__":
ctrl.configure_traits(view=manager_view, context={'pgrid': grid, 'controls': ctrl})

最佳答案

实现此功能的最简单方法是在弹出绘图后在绘图容器上调用 invalidate_and_redraw。在这种情况下,您可以修改对 pop 的调用,如下所示:

plots_container = info.ui.context['pgrid'].plots_container
plots_container.components.pop()
plots_container.invalidate_and_redraw()

更长的讨论:

理想情况下,这将由 Chaco 处理。部分问题在于容器并未设计为直接修改 components 列表。相反,(我猜测)目的是让用户对 components 列表中的项目调用 plots_container.remove

也就是说,似乎也不起作用。事实证明,remove 使当前状态无效,但不请求重绘。 (我的猜测是 chaco/enable 不会自动重绘,因为可能连续有许多缓存无效操作;例如,如果您要从此容器中删除所有绘图,则只需在所有调用之后重绘删除,而不是在每一个之后删除。)

因此,要实际使用这种替代方法,您可以编写如下内容:

plot = plots_container.components[-1]
plots_container.remove(plot)
plots_container.request_redraw()

关于python - 我可以强制我的启用容器从 Traitsui 处理程序重绘吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27322911/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com