在 Slider 中禁用箭头键
disable arrow keys in Slider
当使用 scikit CollectionViewer(简单图像浏览器)时,我希望在滑块获得焦点后按下箭头键不会触发转到 prev/next 图像。我为此使用了 eventFilter
from skimage.viewer import ImageViewer
from skimage.viewer.qt import Qt
from skimage.viewer.widgets import Slider
class SilentViewer(ImageViewer): #CollectionViewer with some modifications
def __init__(self, image_collection, update_on='move', **kwargs):
self.image_collection = image_collection
self.index = 0
self.num_images = len(self.image_collection)
first_image = image_collection[0]
super(SilentViewer, self).__init__(first_image)
slider_kws = dict(value=0, low=0, high=self.num_images - 1)
slider_kws['update_on'] = update_on
slider_kws['callback'] = self.update_index
slider_kws['value_type'] = 'int'
self.slider = Slider('frame', **slider_kws)
self.layout.addWidget(self.slider)
self.installEventFilter(self) #Modification to CollectionViewer №1
def update_index(self, name, index):
index = int(round(index))
if index == self.index:
return
index = max(index, 0)
index = min(index, self.num_images - 1)
self.index = index
self.slider.val = index
self.update_image(self.image_collection[index])
def eventFilter(self,obj,evt): #Modification to CollectionViewer №2
try:
print(evt.type(), evt.key(), evt.text())
if (evt.key() == Qt.Key_Left or
evt.key() == Qt.Key_Right or
evt.key() == Qt.Key_Up or
evt.key() == Qt.Key_Down):
print("Ignored arrow button")
return True
else:
return False
except:
print("Smth went wrong")
return False
#for testing reasons
from skimage import data
from skimage.transform import pyramid_gaussian
img = data.coins()
img_pyr = pyramid_gaussian(img, downscale=2, multichannel=False)
img_collection = tuple(img_pyr)
viewer = SilentViewer(img_collection)
viewer.show()
事件过滤器似乎在工作:按键和其他事件触发控制台输出。但是,箭头键会触发图像更改。如果我更改为 update_on='release'
(请参阅 init),箭头键不会触发图像更改,但会更改滑块位置。
你能告诉我怎样才能让箭头按下被过滤器完全消耗吗?
分析the Slider source code,可以看出它是一个容器,也就是一个widget里面有其他的widget(QLabel,QSlider和QLineEdit),所以filter必须安装在内部的QSlider和不在容器上。
from skimage.viewer import ImageViewer
from skimage.viewer.qt import QtCore
from skimage.viewer.widgets import Slider
class SilentViewer(ImageViewer): # CollectionViewer with some modifications
def __init__(self, image_collection, update_on="move", **kwargs):
self.image_collection = image_collection
self.index = 0
self.num_images = len(self.image_collection)
print(self.num_images)
first_image = image_collection[0]
super(SilentViewer, self).__init__(first_image)
slider_kws = dict(value=0, low=0, high=self.num_images - 1)
slider_kws["update_on"] = update_on
slider_kws["callback"] = self.update_index
slider_kws["value_type"] = "int"
self.slider = Slider("frame", **slider_kws)
self.layout.addWidget(self.slider)
self.slider.slider.installEventFilter(self)
def update_index(self, name, index):
if index == self.index:
return
index = max(index, 0)
index = min(index, self.num_images - 1)
self.index = index
self.update_image(self.image_collection[index])
def eventFilter(self, obj, evt):
if obj is self.slider.slider and evt.type() == QtCore.QEvent.KeyPress:
if evt.key() in (
QtCore.Qt.Key_Left,
QtCore.Qt.Key_Right,
QtCore.Qt.Key_Up,
QtCore.Qt.Key_Down,
):
return True
return super(SilentViewer, self).eventFilter(obj, evt)
def main():
# for testing reasons
from skimage import data
from skimage.transform import pyramid_gaussian
img = data.coins()
img_pyr = pyramid_gaussian(img, downscale=2, multichannel=False)
img_collection = tuple(img_pyr)
viewer = SilentViewer(img_collection)
viewer.show()
if __name__ == "__main__":
main()
当使用 scikit CollectionViewer(简单图像浏览器)时,我希望在滑块获得焦点后按下箭头键不会触发转到 prev/next 图像。我为此使用了 eventFilter
from skimage.viewer import ImageViewer
from skimage.viewer.qt import Qt
from skimage.viewer.widgets import Slider
class SilentViewer(ImageViewer): #CollectionViewer with some modifications
def __init__(self, image_collection, update_on='move', **kwargs):
self.image_collection = image_collection
self.index = 0
self.num_images = len(self.image_collection)
first_image = image_collection[0]
super(SilentViewer, self).__init__(first_image)
slider_kws = dict(value=0, low=0, high=self.num_images - 1)
slider_kws['update_on'] = update_on
slider_kws['callback'] = self.update_index
slider_kws['value_type'] = 'int'
self.slider = Slider('frame', **slider_kws)
self.layout.addWidget(self.slider)
self.installEventFilter(self) #Modification to CollectionViewer №1
def update_index(self, name, index):
index = int(round(index))
if index == self.index:
return
index = max(index, 0)
index = min(index, self.num_images - 1)
self.index = index
self.slider.val = index
self.update_image(self.image_collection[index])
def eventFilter(self,obj,evt): #Modification to CollectionViewer №2
try:
print(evt.type(), evt.key(), evt.text())
if (evt.key() == Qt.Key_Left or
evt.key() == Qt.Key_Right or
evt.key() == Qt.Key_Up or
evt.key() == Qt.Key_Down):
print("Ignored arrow button")
return True
else:
return False
except:
print("Smth went wrong")
return False
#for testing reasons
from skimage import data
from skimage.transform import pyramid_gaussian
img = data.coins()
img_pyr = pyramid_gaussian(img, downscale=2, multichannel=False)
img_collection = tuple(img_pyr)
viewer = SilentViewer(img_collection)
viewer.show()
事件过滤器似乎在工作:按键和其他事件触发控制台输出。但是,箭头键会触发图像更改。如果我更改为 update_on='release'
(请参阅 init),箭头键不会触发图像更改,但会更改滑块位置。
你能告诉我怎样才能让箭头按下被过滤器完全消耗吗?
分析the Slider source code,可以看出它是一个容器,也就是一个widget里面有其他的widget(QLabel,QSlider和QLineEdit),所以filter必须安装在内部的QSlider和不在容器上。
from skimage.viewer import ImageViewer
from skimage.viewer.qt import QtCore
from skimage.viewer.widgets import Slider
class SilentViewer(ImageViewer): # CollectionViewer with some modifications
def __init__(self, image_collection, update_on="move", **kwargs):
self.image_collection = image_collection
self.index = 0
self.num_images = len(self.image_collection)
print(self.num_images)
first_image = image_collection[0]
super(SilentViewer, self).__init__(first_image)
slider_kws = dict(value=0, low=0, high=self.num_images - 1)
slider_kws["update_on"] = update_on
slider_kws["callback"] = self.update_index
slider_kws["value_type"] = "int"
self.slider = Slider("frame", **slider_kws)
self.layout.addWidget(self.slider)
self.slider.slider.installEventFilter(self)
def update_index(self, name, index):
if index == self.index:
return
index = max(index, 0)
index = min(index, self.num_images - 1)
self.index = index
self.update_image(self.image_collection[index])
def eventFilter(self, obj, evt):
if obj is self.slider.slider and evt.type() == QtCore.QEvent.KeyPress:
if evt.key() in (
QtCore.Qt.Key_Left,
QtCore.Qt.Key_Right,
QtCore.Qt.Key_Up,
QtCore.Qt.Key_Down,
):
return True
return super(SilentViewer, self).eventFilter(obj, evt)
def main():
# for testing reasons
from skimage import data
from skimage.transform import pyramid_gaussian
img = data.coins()
img_pyr = pyramid_gaussian(img, downscale=2, multichannel=False)
img_collection = tuple(img_pyr)
viewer = SilentViewer(img_collection)
viewer.show()
if __name__ == "__main__":
main()