python - 禁用 slider 中的箭头键

标签 python pyqt scikit-image eventfilter

当使用 scikit CollectionViewer(简单图像浏览器)时,我想在 slider 获得焦点后按箭头键不触发转到上一个/下一个图像。我为此使用了 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),箭头键不会触发图像更改,但会更改 slider 位置。 您能否告诉我如何使箭头按下被过滤器完全消耗?

最佳答案

分析 the Slider source code ,可以看出它是一个容器,即一个widget,里面有其他widget(QLabel、QSlider和QLineEdit),所以过滤器必须安装在内部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()

关于python - 禁用 slider 中的箭头键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62367144/

相关文章:

python - 日期时间字段接收到原始日期时间

python - Django教程错误: Setting up the test client

python - 在Python中显示一列中n个元素的排列的方法

python - PyQt 获取ListWidget中的特定值

python - 如何从工具栏按钮单击和/或 ctrl + 鼠标滚轮缩放/缩放 QTextEdit 区域

python - 如何在PyQt5中连接QFileSystemModel dataChanged信号?

Python:将图像显示为后台进程?

python - 相当于SkImage中的cv2.INTER_AREA

Python PANDAS 写入 csv : how to set decimal point (".", 或 ",")?

python - Scikit 图片 : resize() got an unexpected keyword argument 'anti_aliasing'