Событие QKeyPress в PyQt

У меня проблемы с моим программным обеспечением. В моем программном обеспечении для фортепиано, если я продолжаю нажимать клавишу на клавиатуре, она воспроизводит несколько повторяющихся одинаковых тонов этой конкретной клавиши. Но на самом деле мне нужен один тон до отпускания этой конкретной клавиши. Я предоставляю часть своего кода, которая обнаруживает событие keyPress и вызывает соответствующий метод. Итак, какие должны быть изменения, которые я должен сделать с моим кодом??

def keyPressEvent(self, event):
    if type(event) == QtGui.QKeyEvent and event.key() == QtCore.Qt.Key_A : 
        self.Playnote('/home/hemanth/hemanth/Piano/C.mp3')
        self.ui.pushButton.animateClick(100)
    if type(event) == QtGui.QKeyEvent and event.key() == QtCore.Qt.Key_S:
        self.Playnote('/home/hemanth/hemanth/Piano/D.mp3')
        self.ui.pushButton_2.animateClick(100)

person Hemanth Raveendran    schedule 06.04.2012    source источник


Ответы (2)


Вы должны проверить event.isAutoRepeat(), чтобы определить, вызвано автоповторением клавиатуры или фактическим нажатием клавиши. Если это автоповтор, игнорируйте это нажатие.

person Brian Campbell    schedule 06.04.2012
comment
@ Брайан Кэмпбелл: Спасибо, все работает :) Я загрузил еще один вопрос. Не могли бы вы мне помочь? - person Hemanth Raveendran; 08.04.2012
comment
@HemanthRaveendran: Разве это не решает только небольшую часть вашей проблемы, когда функция воспроизведения запускается повторно, удерживая нажатой клавишу? Если вы нажмете клавишу более одного раза, разве это не будет той же проблемой? - person jdi; 08.04.2012

Поскольку keyPressEvent всегда будет получать QKeyEvent, вам вообще не нужно будет проверять его тип. Вы уже можете начать с упрощения этого примера:

def keyPressEvent(self, event):
    key = event.key()
    if key == QtCore.Qt.Key_A : 
        self.Playnote('/home/hemanth/hemanth/Piano/C.mp3')
        self.ui.pushButton.animateClick(100)
    elif key == QtCore.Qt.Key_S:
        self.Playnote('/home/hemanth/hemanth/Piano/D.mp3')
        self.ui.pushButton_2.animateClick(100)

Теперь, как вы сказали, это просто будет запускать ваши звуки каждый раз, когда нажимается клавиша. Для получения всей требуемой функциональности потребуется несколько шагов.

  1. Playnote должен иметь возможность продолжать цикл до тех пор, пока не будет остановлен.
  2. Вам нужно сохранить ссылку на этот объект Playnote, чтобы остановить его позже.
  3. KeyReleaseEvent должен будет использовать ссылку Playnote, чтобы остановить его.

1) Playnote нужно зациклить

Если вы используете Phonon для функциональности этого Playnote, вы можете использовать подход, предложенный документами. Это должно было бы соединить сигнал aboutToFinish медиа-объектов с методом, который поставит в очередь другую версию того же медиа-источника.

Это может выглядеть примерно так:

class Playnote(QtCore.QObject):

    def __init__(self, soundFile, parent=None):
        super(Playnote, self).__init__(parent)

        self._isStopped = True

        self.mediaSource = Phonon.MediaSource(soundFile)
        self.mediaObject = Phonon.MediaObject(self)
        self.audioOutput = Phonon.AudioOutput(Phonon.MusicCategory, self)
        Phonon.createPath(self.mediaObject, self.audioOutput)
        self.mediaObject.setCurrentSource(self.mediaSource)

        self.mediaObject.aboutToFinish.connect(self.doRequeue)


    def doRequeue(self):
        if not self._isStopped:
            self.mediaObject.enqueue(self.mediaSource)


    def play(self):
        self._isStopped = True
        # other code here

    def stop(self):
        self._isStopped = False
        # other code here

Вы подключаете этот сигнал к методу, который будет запрашивать тот же звук, если проигрыватель не был остановлен.

2) Нужен объект Playnote

Когда вы запускаете свой звук с помощью keyPressEvent, вам нужно будет сохранить ссылку на объект, который сейчас воспроизводится. Может быть, вы можете создать словарь и сохранить сопоставление ключа с текущим игровым объектом?

# in your class
self.keysPlaying = {}

def keyPressEvent(self, event):
    key = event.key()
    if key == QtCore.Qt.Key_A :
        c_note = Playnote('/home/hemanth/hemanth/Piano/C.mp3')
        self.keysPlaying['c'] = c_note

3) keyReleaseEvent останавливает объект Playnote

Теперь, когда вы запустили и зациклили свой звук, вы можете использовать ссылку, чтобы остановить его позже в keyReleaseEvent:

def keyReleaseEvent(self, event):
    key = event.key()
    if key == QtCore.Qt.Key_A :
        note = self.keysPlaying.get('c', None)
        if note:
            note.stop()
            self.keysPlaying['c'] = None
person jdi    schedule 06.04.2012