禁用滑块中的箭头键

问题描述 投票:2回答:1

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

python pyqt scikit-image eventfilter
1个回答
2
投票

分析the Slider source code,可以看到它是一个容器,即具有其他窗口小部件(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()
© www.soinside.com 2019 - 2024. All rights reserved.