Victoria Price
Victoria Price

Reputation: 637

QSlider and Key Press Event

I currently have a QSlider that scrolls through frames of image data using the mouse. I would like to be able to use the arrow keys to scroll through a single step (one frame).

This is my current sliderMoved code:

def sliderMoved(self,val):
    """
    retrieves the data array for the index value specified by the slider
    """

    if self.fileheader is None:
        print "[DEBUG] change_image_index(): self.fileheader is None"
        return

    idx=val
    self.x=idx
    frame=self.fileheader.frameAtIndex(idx)
    image=scipy.ndimage.filters.maximum_filter(frame.data, size=5)

    self.image.setImage(image, scale=((10.28/512),(2.486/96)))
    print self.image.imageItem.pixelSize()

    def keyPressEvent(self, event):
        if event.key()==Qt.Key_Right:
            frame=self.fileheader.frameAtIndex(idx+1)

To connect the slider to the events, I just use:

self.slider.sliderMoved.connect(self.sliderMoved)
self.slider.sliderMoved.connect(self.keyPressEvent)

The arrow key moves the slider, but it does not cause the image to skip frames... I know I'm missing something silly here...

Upvotes: 3

Views: 6838

Answers (2)

Pratik Dash
Pratik Dash

Reputation: 185

Just an update. Any matplotlib figure can be connected to a key press event and the data plotted can be varied depending on the key pressed. I'm sharing a simple example where the xlabel of a matplotlib figure is not displayed if 'x' key is pressed from the keyboard. Simple modifications on this script can be generalized to greater utility. The example is taken from the following link : https://matplotlib.org/stable/gallery/event_handling/keypress_demo.html

import sys
import numpy as np
import matplotlib.pyplot as plt


def on_press(event):
    print('press', event.key)
    sys.stdout.flush()
    if event.key == 'x':
        visible = xl.get_visible()
        xl.set_visible(not visible)
        fig.canvas.draw()


# Fixing random state for reproducibility
np.random.seed(19680801)

fig, ax = plt.subplots()

fig.canvas.mpl_connect('key_press_event', on_press)

ax.plot(np.random.rand(12), np.random.rand(12), 'go')
xl = ax.set_xlabel('easy come, easy go')
ax.set_title('Press a key')
plt.show()

Upvotes: 0

Gary Hughes
Gary Hughes

Reputation: 4510

Try connecting to the slider's valueChanged rather than sliderMoved.

import sys
from PyQt4.QtCore import Qt
from PyQt4.QtGui import QApplication, QWidget, QSlider, QLabel, QVBoxLayout

class Widget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.v_layout = QVBoxLayout()

        self.slider = QSlider()
        self.slider.setOrientation(Qt.Horizontal)
        self.label = QLabel('Slider at position 0')

        self.v_layout.addWidget(self.label)
        self.v_layout.addWidget(self.slider)

        self.setLayout(self.v_layout)

        self.slider.valueChanged.connect(self.slider_moved)

    def keyPressEvent(self, event):
        if event.key()==Qt.Key_Right:
            self.slider.setValue(self.slider.value() + 1)
        elif event.key()==Qt.Key_Left:
            self.slider.setValue(self.slider.value() - 1)
        else:
            QWidget.keyPressEvent(self, event)

    def slider_moved(self, position):
        self.label.setText('Slider at position %d' % position)


if __name__ == '__main__':
  app = QApplication(sys.argv)

  widget = Widget()
  widget.show()

  sys.exit(app.exec_())

From your keyPressEvent you can just change the value of the slider which will cause whatever functions that are connected to valueChanged to run.

Upvotes: 7

Related Questions