I am having issues with my software. In my piano software if I keep pressing a key on the keyboard then it is making multiple repeated same tones of that particular key. But actually I need a single tone until the release of that particular key. I'm providing a part of my code that detects the keyPress event and calls the corresponding method. So what should be the changes that I've to do with my code??
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)
You should check event.isAutoRepeat()
to determine if the event is caused by keyboard autorepeat or an actual keypress. If it is an autorepeat, ignore that press.
Since a keyPressEvent will always receive a QKeyEvent, you won't need to check its type at all. You can already start by simplifying this example:
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)
Now, like you said, this will simply fire your sounds every time a key is pressed. There would be a few steps needed to get the entire functionality you require.
Playnote
needs to be able to keep looping until told to stopPlaynote
object in order to stop it laterPlaynote
reference to stop itPlaynote
needs to loopIf you are using Phonon for the functionality of this Playnote
, then you can use an approach suggested by the docs. This would be to connect the Media Objects' aboutToFinish
signal to a method that will enqueue another version of the same media source.
It might look something like this:
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
You are connecting that signal to a method that will requeue the same sound if the player has not been stopped.
Playnote
objectWhen you start your sound with the keyPressEvent, you will have to store a reference to the object that is now playing. Maybe you can create a dictionary, and store a mapping of the key to the current playing object?
# 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
Playnote
objectNow that you have started, and looped your sound, you can use the reference to stop it later in a 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With