PyQ中的QKeyPress事件

2024-05-29 09:37:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我的软件有问题。在我的钢琴软件中,如果我一直按键盘上的一个键,那么它就会重复多次同一个键的音调。但实际上我需要一个单一的音调,直到释放特定的关键。我提供了一部分代码来检测按键事件并调用相应的方法。那么我的代码应该做些什么呢??

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)

Tags: andkey代码selfeventif软件type
2条回答

因为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需要循环

如果你使用声子来实现这个功能,那么你可以使用声子。这将把媒体对象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对象

现在您已经开始并循环您的声音,您可以在稍后的keyreaseevent中使用引用来停止它:

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

您应该检查^{}以确定事件是由键盘自动重放还是实际的按键引起的。如果是自动重放,就忽略这个按键。

相关问题 更多 >

    热门问题