3

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...

demonplus
  • 5,613
  • 12
  • 49
  • 68
Victoria Price
  • 637
  • 3
  • 13
  • 26

2 Answers2

7

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.

Gary Hughes
  • 4,400
  • 1
  • 26
  • 40
0

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()
Pratik Dash
  • 81
  • 1
  • 10
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/late-answers/31907141) – Emi OB Jun 01 '22 at 08:12
  • @EmiOB I've added the small example from the link that makes it easier to understand the usage. I can't be fully specific in answering this particular question because I didn't have the exact same problem. The question and the accepted answers helped me in finding the link which solved my problem and hence I thought that I should mention it here in case someone else may also need it. I hope that will be sufficient. – Pratik Dash Jun 01 '22 at 09:35