如何在silx viewer Plot2D中实现滑块切换时图像修改持久化?
问题描述
使用自定义silx viewer可视化单个HDF5文件中的系列图像时,默认Plot2D组件的滑块可切换图像:
已实现一个自定义SumAction,功能是给图像每个像素加100,但切换滑块时之前的修改会消失。希望实现:当SumAction按钮处于勾选状态时,切换图像自动执行修改,让效果看起来持久化。
现有核心代码片段:
class SumAction(PlotAction): def __init__(self, plot, parent=None): sum_icon = qt.QIcon("./matrix.png") super(SumAction, self).__init__( plot, icon=sum_icon, text='Sum', tooltip='Sum 100 to each image pixel.', triggered=self.__sum, checkable=True, parent=parent) def __sum(self, checked): activeImage = self.plot.getActiveImage() if activeImage is None: qt.QMessageBox.information( self.plot, "Plot data is None. Open a valid 2D image to use this function." ) data = activeImage.getData() self.originalData = activeImage.getData() data+=100 activeImage.setData(data)
解决方案
不需要重写滑块函数,通过监听Plot2D的图像切换信号,结合SumAction的勾选状态,自动对新切换的图像应用修改即可。关键是要保存每个图像的原始数据,避免重复叠加修改,同时在图像切换时触发处理逻辑。
修改后的完整代码如下:
#!/usr/bin/env python import sys import numpy from silx.gui import qt def createWindow(parent, settings): # Local import to avoid early import (like h5py) # Some libraries have to be configured first properly from silx.gui.plot.actions import PlotAction from silx.app.view.Viewer import Viewer from silx.app.view.ApplicationContext import ApplicationContext class SumAction(PlotAction): def __init__(self, plot, parent=None): sum_icon = qt.QIcon("./matrix.png") super(SumAction, self).__init__( plot, icon=sum_icon, text='Sum', tooltip='Sum 100 to each image pixel.', triggered=self.__sum, checkable=True, parent=parent) # 存储每个图像的原始数据,以图像对象为键 self.original_data_map = {} # 监听活动图像变化信号 self.plot.activeImageChanged.connect(self.__onImageChanged) def __sum(self, checked): active_image = self.plot.getActiveImage() if active_image is None: qt.QMessageBox.information( self.plot, "Plot data is None. Open a valid 2D image to use this function." ) return if checked: # 保存原始数据(仅第一次勾选时保存) if active_image not in self.original_data_map: self.original_data_map[active_image] = active_image.getData().copy() # 应用修改 modified_data = self.original_data_map[active_image] + 100 active_image.setData(modified_data) else: # 取消勾选时恢复原始数据 if active_image in self.original_data_map: active_image.setData(self.original_data_map[active_image]) def __onImageChanged(self, new_image, old_image): # 切换图像时,如果按钮处于勾选状态,自动应用修改 if self.isChecked() and new_image is not None: if new_image not in self.original_data_map: self.original_data_map[new_image] = new_image.getData().copy() modified_data = self.original_data_map[new_image] + 100 new_image.setData(modified_data) class MyApplicationContext(ApplicationContext): """This class is shared to all the silx view application.""" def findPrintToolBar(self, plot): # FIXME: It would be better to use the Qt API return plot._outputToolBar def viewWidgetCreated(self, view, widget): """Called when the widget of the view was created. So we can custom it. """ from silx.gui.plot import Plot2D if isinstance(widget, Plot2D): toolBar = self.findPrintToolBar(widget) action = SumAction(widget, widget) toolBar.addAction(action) class MyViewer(Viewer): def createApplicationContext(self, settings): return MyApplicationContext(self, settings) window = MyViewer(parent=parent, settings=settings) window.setWindowTitle(window.windowTitle() + " [custom]") return window def main(args): from silx.app.view import main as silx_view_main # Monkey patch the main window creation silx_view_main.createWindow = createWindow # Use the default launcher silx_view_main.main(args) if __name__ == '__main__': main(sys.argv)
关键修改说明:
- 添加
original_data_map字典,存储每个图像对象对应的原始数据,避免重复叠加修改(防止多次切换后像素值持续增加)。 - 连接
plot.activeImageChanged信号到__onImageChanged槽函数,当切换图像时自动触发修改逻辑。 - 在
__sum函数中,勾选时保存原始数据并应用修改;取消勾选时恢复原始数据。 - 在
__onImageChanged函数中,检测到按钮勾选且有新图像时,自动对新图像应用修改。
内容的提问来源于stack exchange,提问作者Marco Montevechi Filho
相关产品推荐
相关产品推荐

