def __init__(self, parent=None): super(LlpMainWindow, self).__init__(parent) self.setupUi(self) # Setup instance variables self._playIcon = QIcon() self._playIcon.addPixmap(QPixmap(":/Images/Play")) self._pauseIcon = QIcon() self._pauseIcon.addPixmap(QPixmap(":/Images/Pause")) self._filename = None self._total = 0 self._numDps = 1 self._oldMs = 0 self._beatsLeft = 0 self._beatTimer = None self._rewinding = None self._forwarding = None self._wasPlaying = False self._zoom = 1 self._spool = 0 self._controls = ControlSet() self._scene = MarkedScene(self) self._media = Phonon.MediaObject(self) self._filterList = [] self._audio = Phonon.AudioOutput(Phonon.MusicCategory, self) self._hsc = self.markView.horizontalScrollBar() settings = QSettings() self.recentFiles = [unicode(fname) for fname in settings.value("RecentFiles").toStringList() if os.path.exists(unicode(fname))] self._knownSongMarks = {} self._currentSongHash = None self._loadKnownMarks(settings) # Connect signals self._media.totalTimeChanged.connect(self._totalChanged) self._media.stateChanged.connect(self._mediaStateChanged) self._media.setTickInterval(TICK_INTERVAL) self._media.metaDataChanged.connect(self.printMeta) self._media.tick.connect(self._tick) self._media.prefinishMarkReached.connect(self._prefinish) self._media.finished.connect(self._finish) self._hsc.valueChanged.connect(self._setWindow) self._scene.currentChanged.connect(self.setCurrent) self.volumeSlider.setAudioOutput(self._audio) self.actionStartRewind.triggered.connect(self.on_rewindButton_pressed) self.actionEndRewind.triggered.connect(self.on_rewindButton_released) self.actionStartForward.triggered.connect(self.on_forwardButton_pressed) self.actionEndForward.triggered.connect(self.on_forwardButton_released) # Final setup self.markView.setScene(self._scene) self.globalView.setScene(self._scene) Phonon.createPath(self._media, self._audio) self._setSpool() self._tick(0) self._checkButtons() self._setupActions() self._mimeTypes = set() self._getAvailableMusicTypes() self._buildTypeFilter() self._updateRecent()
def __init__(self, parent=None): super(LlpMainWindow, self).__init__(parent) self.setupUi(self) # Setup instance variables self._playIcon = QIcon() self._playIcon.addPixmap(QPixmap(":/Images/Play")) self._pauseIcon = QIcon() self._pauseIcon.addPixmap(QPixmap(":/Images/Pause")) self._filename = None self._total = 0 self._numDps = 1 self._oldMs = 0 self._beatsLeft = 0 self._beatTimer = None self._rewinding = None self._forwarding = None self._wasPlaying = False self._zoom = 1 self._spool = 0 self._controls = ControlSet() self._scene = MarkedScene(self) self._media = Phonon.MediaObject(self) self._filterList = [] self._audio = Phonon.AudioOutput(Phonon.MusicCategory, self) self._hsc = self.markView.horizontalScrollBar() settings = QSettings() self.recentFiles = [ unicode(fname) for fname in settings.value("RecentFiles").toStringList() if os.path.exists(unicode(fname)) ] self._knownSongMarks = {} self._currentSongHash = None self._loadKnownMarks(settings) # Connect signals self._media.totalTimeChanged.connect(self._totalChanged) self._media.stateChanged.connect(self._mediaStateChanged) self._media.setTickInterval(TICK_INTERVAL) self._media.metaDataChanged.connect(self.printMeta) self._media.tick.connect(self._tick) self._media.prefinishMarkReached.connect(self._prefinish) self._media.finished.connect(self._finish) self._hsc.valueChanged.connect(self._setWindow) self._scene.currentChanged.connect(self.setCurrent) self.volumeSlider.setAudioOutput(self._audio) self.actionStartRewind.triggered.connect(self.on_rewindButton_pressed) self.actionEndRewind.triggered.connect(self.on_rewindButton_released) self.actionStartForward.triggered.connect(self.on_forwardButton_pressed) self.actionEndForward.triggered.connect(self.on_forwardButton_released) # Final setup self.markView.setScene(self._scene) self.globalView.setScene(self._scene) Phonon.createPath(self._media, self._audio) self._setSpool() self._tick(0) self._checkButtons() self._setupActions() self.grabKeyboard() self._mimeTypes = set() self._checkMusicType("Mp3", ["mp3"], ["audio/mp3", "audio/mpeg3"]) self._checkMusicType("Mp4", ["m4a", "mp4"], ["audio/mp4", "audio/mp4a-latm"]) allExtensions = [] for unusedName, extList in self._filterList: allExtensions.extend(extList) self._filterList.insert(0, ("Any", ["*.*"])) self._filterList.insert(0, ("Music files", allExtensions)) filters = [ "%s (%s)" % (name, " ".join("*.%s" % ext for ext in extList)) for (name, extList) in self._filterList ] self._filter = ";;".join(filters) self._updateRecent()
class LlpMainWindow(QMainWindow, Ui_LlpMainWindow): # IGNORE:R0902+R0904 def __init__(self, parent=None): super(LlpMainWindow, self).__init__(parent) self.setupUi(self) # Setup instance variables self._playIcon = QIcon() self._playIcon.addPixmap(QPixmap(":/Images/Play")) self._pauseIcon = QIcon() self._pauseIcon.addPixmap(QPixmap(":/Images/Pause")) self._filename = None self._total = 0 self._numDps = 1 self._oldMs = 0 self._beatsLeft = 0 self._beatTimer = None self._rewinding = None self._forwarding = None self._wasPlaying = False self._zoom = 1 self._spool = 0 self._controls = ControlSet() self._scene = MarkedScene(self) self._media = Phonon.MediaObject(self) self._filterList = [] self._audio = Phonon.AudioOutput(Phonon.MusicCategory, self) self._hsc = self.markView.horizontalScrollBar() settings = QSettings() self.recentFiles = [ unicode(fname) for fname in settings.value("RecentFiles").toStringList() if os.path.exists(unicode(fname)) ] self._knownSongMarks = {} self._currentSongHash = None self._loadKnownMarks(settings) # Connect signals self._media.totalTimeChanged.connect(self._totalChanged) self._media.stateChanged.connect(self._mediaStateChanged) self._media.setTickInterval(TICK_INTERVAL) self._media.metaDataChanged.connect(self.printMeta) self._media.tick.connect(self._tick) self._media.prefinishMarkReached.connect(self._prefinish) self._media.finished.connect(self._finish) self._hsc.valueChanged.connect(self._setWindow) self._scene.currentChanged.connect(self.setCurrent) self.volumeSlider.setAudioOutput(self._audio) self.actionStartRewind.triggered.connect(self.on_rewindButton_pressed) self.actionEndRewind.triggered.connect(self.on_rewindButton_released) self.actionStartForward.triggered.connect(self.on_forwardButton_pressed) self.actionEndForward.triggered.connect(self.on_forwardButton_released) # Final setup self.markView.setScene(self._scene) self.globalView.setScene(self._scene) Phonon.createPath(self._media, self._audio) self._setSpool() self._tick(0) self._checkButtons() self._setupActions() self.grabKeyboard() self._mimeTypes = set() self._checkMusicType("Mp3", ["mp3"], ["audio/mp3", "audio/mpeg3"]) self._checkMusicType("Mp4", ["m4a", "mp4"], ["audio/mp4", "audio/mp4a-latm"]) allExtensions = [] for unusedName, extList in self._filterList: allExtensions.extend(extList) self._filterList.insert(0, ("Any", ["*.*"])) self._filterList.insert(0, ("Music files", allExtensions)) filters = [ "%s (%s)" % (name, " ".join("*.%s" % ext for ext in extList)) for (name, extList) in self._filterList ] self._filter = ";;".join(filters) self._updateRecent() # for eff in Phonon.BackendCapabilities.availableAudioEffects(): # print eff.name() def _checkMusicType(self, name, extensions, mimeTypes): for mType in mimeTypes: if Phonon.BackendCapabilities.isMimeTypeAvailable(mType): self._filterList.append((name, extensions)) break def _setupActions(self): self.addActions( [ self.actionPlay, self.actionCountIn, self.actionMark, self.actionMark_2, self.actionHome, self.actionEnd, self.actionNextMark, self.actionPreviousMark, self.actionLoop, self.actionSelection, self.actionOpen, self.actionToggleMute, self.actionVolumeUp, self.actionVolumeDown, self.actionZoomIn, self.actionZoomOut, self.actionPageDown, self.actionPageUp, self.actionSetBegin, self.actionSetBegin_2, self.actionSetEnd, self.actionSetEnd_2, self.actionTrack, ] ) self._controls.addSingleAction(self.actionHome, "Go to start", operations.HOME) self._controls.addActionPair( self.actionStartRewind, self.actionEndRewind, Qt.Key_Left, "Rewind", operations.REWIND ) self._controls.addSingleAction(self.actionPlay, "Play/pause playback", operations.PLAY) self._controls.addSingleAction(self.actionCountIn, "Start count in", operations.COUNT) self._controls.addActionPair( self.actionStartForward, self.actionEndForward, Qt.Key_Right, "Fast Forward", operations.FFWD ) self._controls.addSingleAction(self.actionEnd, "Go to end", operations.END) self._controls.addSingleAction(self.actionMark, "Set/delete mark", operations.MARK) self._controls.addSingleAction(self.actionSetBegin, "Set selection start", operations.SETBEGIN) self._controls.addSingleAction(self.actionPreviousMark, "Go to previous mark", operations.PREV) self._controls.addSingleAction(self.actionSetEnd, "Set selection end", operations.SETEND) self._controls.addSingleAction(self.actionNextMark, "Go to next mark", operations.NEXT) self._controls.addSingleAction(self.actionLoop, "Toggle looping", operations.LOOP) self._controls.addSingleAction(self.actionSelection, "Toggle song/selection playback", operations.SONG) self._controls.addSingleAction(self.actionTrack, "Toggle playback tracking", operations.TRACK) self._controls.addSingleAction(self.actionZoomIn, "Zoom In", operations.ZOOMIN) self._controls.addSingleAction(self.actionZoomOut, "Zoom Out", operations.ZOOMOUT) self._controls.addSingleAction(self.actionToggleMute, "Toggle Mute", operations.MUTE) self._controls.addSingleAction(self.actionVolumeUp, "Volume Up", operations.VOLUP) self._controls.addParameterAction(self._setVolume, "Set Volume", 0, 1, operations.SETVOL) self._controls.addSingleAction(self.actionVolumeDown, "Volume Down", operations.VOLDN) self._controls.addParameterAction(self._setPlaybackTime, "Set playback time", 0, 1, operations.SETTIME) settings = QSettings() data = str(settings.value("Controls").toString()) if data: handle = StringIO(data) self._controls.load(handle) def printMeta(self): for k, v in self._media.metaData().iteritems(): print str(k), str(v) @pyqtSignature("") def on_actionOpen_triggered(self): if not self.openButton.isEnabled(): return if self._media.state() == Phonon.PlayingState: self._media.pause() if self._filename is not None: directory = os.path.dirname(self._filename) else: loc = QDesktopServices.MusicLocation directory = QDesktopServices.storageLocation(loc) caption = "Open a music file" fname = QFileDialog.getOpenFileName(parent=self, caption=caption, directory=directory, filter=self._filter) if len(fname) == 0: return self._saveCurrentMarks() self._loadSong(fname) def _loadSong(self, fname): fname = unicode(fname) self._filename = fname self._calculateSongHash() source = Phonon.MediaSource(fname) self._media.setCurrentSource(source) self._scene.newSong() self._media.pause() # Makes sure tick signals are emitted if self._currentSongHash in self._knownSongMarks: self._scene.loadMarksFromList(self._knownSongMarks[self._currentSongHash]) self.setZoom(1) base = os.path.splitext(os.path.basename(self._filename))[0] self.setWindowTitle(WINDOW_TITLE + " - " + base) self._updateRecent() def _updateRecent(self): if self._filename is not None: if self._filename in self.recentFiles: self.recentFiles.remove(self._filename) self.recentFiles.insert(0, self._filename) if len(self.recentFiles) > 50: self.recentFiles.pop() settings = QSettings() settings.setValue("RecentFiles", QVariant(self.recentFiles)) try: self.recentFilesBox.blockSignals(True) self.recentFilesBox.clear() self.recentFilesBox.addItem("Recent Song Files") for fname in self.recentFiles: base = os.path.splitext(os.path.basename(fname))[0] if fname != self._filename and os.path.exists(fname): self.recentFilesBox.addItem(base, userData=QVariant(fname)) self.recentFilesBox.setEnabled(len(self.recentFiles) > 0) self.recentFilesBox.setCurrentIndex(0) finally: self.recentFilesBox.blockSignals(False) @pyqtSignature("int") def on_recentFilesBox_currentIndexChanged(self, index): if index == 0: return filename = unicode(self.recentFilesBox.itemData(index).toString()) self._loadSong(filename) @pyqtSignature("") def on_actionPlay_triggered(self): if not self.playButton.isEnabled(): return if self._media.state() == Phonon.PlayingState: self._media.pause() elif self._media.state() in (Phonon.PausedState, Phonon.StoppedState): self._media.play() def _mediaStateChanged(self, newState): self._checkButtons(newState) if newState == Phonon.ErrorState: eString = str(self._media.errorString()) if eString.endswith("(0x80040265)"): QMessageBox.warning( self, "Unsupported codec", "You do not have the correct codec " "installed to play back this sort of file", ) elif eString.endswith("(0x80040266)"): QMessageBox.warning(self, "ID3 tag error", "Cannot read compressed ID3 tags: " + eString) else: QMessageBox.warning(self, "Unknown error opening file", eString) self._totalChanged(0) def _checkButtons(self, state=None, ms=None): if state is None: state = self._media.state() if ms is None: ms = self._media.currentTime() if state in (Phonon.LoadingState, Phonon.BufferingState, Phonon.ErrorState): self.centerFrame.setEnabled(False) self.controlsFrame.setEnabled(False) self.countFrame.setEnabled(False) else: if not self.viewFrame.isEnabled(): self.centerFrame.setEnabled(True) self.controlsFrame.setEnabled(True) self.countFrame.setEnabled(True) if state == Phonon.PlayingState or ((self._rewinding or self._forwarding) and self._wasPlaying): self.playButton.setIcon(self._pauseIcon) self.countButton.setEnabled(False) self.selectionButton.setEnabled(False) self.loopButton.setEnabled(False) else: self.playButton.setIcon(self._playIcon) self.countButton.setEnabled(True) self.selectionButton.setEnabled(True) self.loopButton.setEnabled(True) beforeEnd = ms < self._total self.playButton.setEnabled(beforeEnd) self.countButton.setEnabled(self.countButton.isEnabled() and beforeEnd) self.endButton.setEnabled(beforeEnd) self.forwardButton.setEnabled(beforeEnd) if not beforeEnd and self._forwarding: self.on_forwardButton_released() afterStart = ms != 0 self.startButton.setEnabled(afterStart) self.rewindButton.setEnabled(afterStart) if not afterStart and self._rewinding: self.on_rewindButton_released() @pyqtSignature("") def on_actionHome_triggered(self): if not self.startButton.isEnabled(): return if self.selectionButton.isChecked() and self._scene.begin is not None: self._media.seek(self._scene.begin) else: self._media.seek(0) @pyqtSignature("") def on_actionEnd_triggered(self): if not self.endButton.isEnabled(): return if self.selectionButton.isChecked() and self._scene.end is not None: self._media.seek(self._scene.end) else: self._media.seek(self._total) @pyqtSignature("") def on_rewindButton_pressed(self): if not self._rewinding: self._rewinding = QTimer(self) self._wasPlaying = self._media.state() == Phonon.PlayingState self._rewinding.setInterval(TICK_INTERVAL) self._rewinding.timeout.connect(self._rewinder) self._media.pause() self._rewinding.start() def _rewinder(self): newPos = max(0, self._oldMs - self._spool) self._media.seek(newPos) @pyqtSignature("") def on_rewindButton_released(self): if self._rewinding: self._rewinding.stop() if self._wasPlaying: self._media.play() self._rewinding = None @pyqtSignature("") def on_forwardButton_pressed(self): self._wasPlaying = self._media.state() == Phonon.PlayingState self._forwarding = QTimer(self) self._forwarding.setInterval(TICK_INTERVAL) self._forwarding.timeout.connect(self._forwarder) self._media.pause() self._forwarding.start() def _forwarder(self): newPos = min(self._total, self._oldMs + self._spool) self._media.seek(newPos) @pyqtSignature("") def on_forwardButton_released(self): if self._forwarding: self._forwarding.stop() if self._wasPlaying: self._media.play() self._forwarding = None def _tick(self, ms): seconds = ms / 1000.0 if self._total == 0: self.positionIndicator.setText("--") else: self.positionIndicator.setText("%0*.2f" % (self._numDps, seconds)) if ms < self._oldMs or ms == self._total or self._oldMs == 0: self._checkButtons(ms=ms) self._oldMs = ms self._scene.setCurrent(ms) self._doTracking() def setCurrent(self, ms): self._media.seek(ms) def _totalChanged(self, total): self._total = total if total > 0: self.centerFrame.setEnabled(True) self.controlsFrame.setEnabled(True) self.countFrame.setEnabled(True) self._numDps = 1 tens = 10 while tens <= total: self._numDps += 1 tens *= 10 self.totalLabel.setText("%.2f" % (total / 1000.0)) self._scene.setTotal(total, self._zoom) self.markView.setViewportMargins(0, 0, 0, 0) self._tick(self._media.currentTime()) self.markView.setSceneRect(self._scene.sceneRect()) self.globalView.setSceneRect(self._scene.sceneRect()) sx = float(self.globalView.viewport().width() - 1) / self._scene.width() height = self.globalView.viewport().height() - 1 sy = float(height) / self._scene.height() transform = QTransform(sx, 0, 0, 0, sy, 0, 0, 0, 1) self.globalView.setTransform(transform) self._changeTransform() else: self.totalLabel.setText("--") self._scene.setTotal(total, self._zoom) self._tick(0) self.markView.setSceneRect(0, 0, 0, 0) self.globalView.setSceneRect(0, 0, 0, 0) self.centerFrame.setEnabled(False) self.controlsFrame.setEnabled(False) self.countFrame.setEnabled(False) self.setZoom() def _changeTransform(self): sx = float(self._zoom * (self.markView.viewport().width())) / self._scene.width() height = self.markView.viewport().height() - 1 sy = float(height) / self._scene.height() transform = QTransform(sx, 0, 0, 0, sy, 0, 0, 0, 1) self.markView.setTransform(transform) self.markView.setSceneRect(self._scene.sceneRect()) @pyqtSignature("") def on_actionSetBegin_triggered(self): if self.setBeginButton.isEnabled(): self._scene.begin = self._oldMs @pyqtSignature("") def on_actionSetEnd_triggered(self): if self.setEndButton.isEnabled(): self._scene.end = self._oldMs self._media.setPrefinishMark(self._total - self._oldMs) @pyqtSignature("") def on_actionMark_triggered(self): if self.markButton.isEnabled(): self._scene.toggleMark(self._oldMs) @pyqtSignature("") def on_actionNextMark_triggered(self): if self.nextMarkButton.isEnabled(): mark = self._scene.getNextMark(self._oldMs) self._media.seek(mark) @pyqtSignature("") def on_actionPreviousMark_triggered(self): if self.prevMarkButton.isEnabled(): mark = self._scene.getPreviousMark(self._oldMs) self._media.seek(mark) def _prefinish(self): if self.selectionButton.isChecked(): self._media.pause() if self.loopButton.isChecked(): self._media.seek(self._scene.begin) self._media.play() def _finish(self): if self.loopButton.isChecked() and not self.selectionButton.isChecked(): self._media.pause() self._media.seek(0) self._media.play() @pyqtSignature("") def on_actionSelection_triggered(self): if self.selectionButton.isEnabled(): self.selectionButton.toggle() @pyqtSignature("") def on_actionLoop_triggered(self): if self.loopButton.isEnabled(): self.loopButton.toggle() @pyqtSignature("") def on_actionTrack_triggered(self): if self.trackButton.isEnabled(): self.trackButton.toggle() self._doTracking() @pyqtSignature("") def on_actionCountIn_triggered(self): if not self.countButton.isEnabled(): return numBeats = self.beatsBox.value() if numBeats == 0: self.actionPlay.trigger() self.playButton.setFocus() return bpm = self.bpmBox.value() interval = 60000.0 / bpm self._beatsLeft = numBeats self._beatTimer = QTimer(self) self._beatTimer.setInterval(interval) self._beatTimer.timeout.connect(self._beat) self.centerFrame.setEnabled(False) self.controlsFrame.setEnabled(False) self.countFrame.setEnabled(False) self.toolsFrame.setEnabled(False) self._beatTimer.start(interval) def _beat(self): if self._beatsLeft <= 0: self._beatTimer.stop() self.centerFrame.setEnabled(True) self.controlsFrame.setEnabled(True) self.countFrame.setEnabled(True) self.toolsFrame.setEnabled(True) self.actionPlay.trigger() self.playButton.setFocus() else: self._scene.flash() self._beatsLeft -= 1 @pyqtSignature("") def on_actionToggleMute_triggered(self): self._audio.setMuted(not self._audio.isMuted()) @pyqtSignature("") def on_actionVolumeUp_triggered(self): newVolume = min(self.volumeSlider.maximumVolume(), self._audio.volume() + self.volumeSlider.pageStep() / 100.0) self._audio.setVolume(newVolume) @pyqtSignature("") def on_actionVolumeDown_triggered(self): newVolume = max(0, self._audio.volume() - self.volumeSlider.pageStep() / 100.0) self._audio.setVolume(newVolume) def setZoom(self, zoom=None): if zoom is not None: self._zoom = zoom self._scene.setZoom(zoom) self._setSpool() self._checkZoomButtons() self._doTracking() def _setSpool(self): if self._total > 0: self._spool = (SPOOL_INTERVAL / 100.0) * (self._total / self._zoom) else: self._spool = 0 @pyqtSignature("") def on_actionZoomIn_triggered(self): if not self.zoomInButton.isEnabled(): return if self._zoom < MAX_ZOOM: self.setZoom(self._zoom * 2) self._changeTransform() self._checkZoomButtons() @pyqtSignature("") def on_actionZoomOut_triggered(self): if not self.zoomOutButton.isEnabled(): return if self._zoom > MIN_ZOOM: self.setZoom(self._zoom / 2) self._changeTransform() self._checkZoomButtons() def _checkZoomButtons(self): self.zoomInButton.setEnabled(self._zoom < MAX_ZOOM) self.zoomOutButton.setEnabled(self._zoom > MIN_ZOOM) self.trackButton.setDisabled(self._zoom == 1) @pyqtSignature("") def on_actionPageUp_triggered(self): if self.viewFrame.isEnabled() and self._zoom != 1: self._hsc.triggerAction(self._hsc.SliderPageStepSub) @pyqtSignature("") def on_actionPageDown_triggered(self): if self.viewFrame.isEnabled() and self._zoom != 1: self._hsc.triggerAction(self._hsc.SliderPageStepAdd) def _doTracking(self): if self.trackButton.isEnabled() and self.trackButton.isChecked(): self.markView.centerOn(self._oldMs, 0) def _setWindow(self, unusedValue): topLeft = self.markView.mapToScene(0, 0) self._scene.setWindow(topLeft, self._zoom) @pyqtSignature("") def on_settingsButton_clicked(self): dlg = EditControlsDialog(self._controls, self) if dlg.exec_(): handle = StringIO() self._controls.save(handle) data = QVariant(handle.getvalue()) settings = QSettings() settings.setValue("Controls", data) def _calculateSongHash(self): with open(self._filename, "rb") as songfile: data = songfile.read() self._currentSongHash = md5(data).hexdigest() def _saveCurrentMarks(self): if self._currentSongHash is None: return settings = QSettings() settings.beginGroup("Marks") try: marks = self._scene.listMarks() settings.setValue(self._currentSongHash, QVariant(marks)) finally: settings.endGroup() def _loadKnownMarks(self, settings): settings.beginGroup("Marks") try: for songHash in settings.allKeys(): markList = str(settings.value(songHash).toString()) self._knownSongMarks[str(songHash)] = markList finally: settings.endGroup() def closeEvent(self, event): self._saveCurrentMarks() self._controls.closeMidiDevice() super(LlpMainWindow, self).closeEvent(event) def keyPressEvent(self, event): if event.isAutoRepeat(): event.accept() elif event.key() == Qt.Key_Left: if not self._rewinding: self.actionStartRewind.trigger() event.accept() elif event.key() == Qt.Key_Right: if not self._forwarding: self.actionStartForward.trigger() event.accept() else: event.ignore() def keyReleaseEvent(self, event): if event.isAutoRepeat(): event.ignore() elif event.key() == Qt.Key_Left: if self._rewinding: self.actionEndRewind.trigger() event.accept() elif event.key() == Qt.Key_Right: if self._forwarding: self.actionEndForward.trigger() event.accept() else: event.ignore() def _setVolume(self, value): self._audio.setVolume(value) def _setPlaybackTime(self, value): position = int(value * self._total + 0.5) self._media.seek(position)