1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
| #!/usr/bin/python
# -*- coding: utf-8 -*-
## But du programme: Modifier le tempo dun fichier mp3 grace à PySox, tout en gardant lUI utilisable
## Dépendances : pyside, libsox-dev, libsox-fmt-mp3, pysox ( https://pypi.python.org/pypi/pysox/0.3.6.alpha )
## 2 variables à modifier:
#### inputFile (ligne 49)
#### outputFile (ligne 51)
## Explication du code :
#### Le bouton depart lance le thread contenant les instructions PySox.
######## Ce thread est censé modifier le label_Directory de Fenetre avant de \
######## lancer le processus, mais ne le fait quune fois la transformation finie
#### Le bouton arret devrait arrêter le thread en route. Mais comment?
######## PROBLÈME*MAJEUR #########
## Pysox ne peut rendre la main. LUI freeze.
from __future__ import division, print_function, unicode_literals
import sys, os, time
from PySide import QtCore, QtGui
import pysox
#############################################################################
class Operationlongue(QtCore.QThread):
# création des nouveaux signaux
info = QtCore.Signal(str) # signal pour une progression
fini = QtCore.Signal(bool) # signal pour la fin du thread
#========================================================================
def __init__(self, parent=None):
super(Operationlongue, self).__init__(parent)
self.stop = False # drapeau pour signaler l'arrêt demandé
#========================================================================
def run(self):
## Prendre un fichier mp3 existant en input (court, de préférence, pour que PySox ne mette pas trop de temps)
inputFile = "/home/user/mydir/music/input.mp3"
## Chemin de la copie qui sortira en output
outputFile = "/home/user/mydir/music/output.mp3"
self.info.emit(inputFile)
soxApp = pysox.CSoxApp(inputFile, outputFile, effectparams=[ ("tempo", [ b'1,2' ]), ])
soxApp.flow()
self.fini.emit(self.stop) # envoi du signal de fin d'exécution du thread
#========================================================================
def arreter(self):
"""pour arrêter avant la fin normale d'exécution du thread"""
self.stop = True
#############################################################################
class Fenetre(QtGui.QWidget):
#========================================================================
def __init__(self, parent=None):
super(Fenetre,self).__init__(parent)
# bouton de lancement du thread
self.depart = QtGui.QPushButton(u"Départ", self)
self.depart.clicked.connect(self.lancement)
# bouton d'arrêt anticipé du thread
self.arret = QtGui.QPushButton(u"Arrêt", self)
self.arret.clicked.connect(self.arreter)
# Dossier
self.label_Directory = QtGui.QLabel("Test")
# positionne les widgets dans la fenêtre
posit = QtGui.QGridLayout()
posit.addWidget(self.depart, 0, 0)
posit.addWidget(self.arret, 1, 0)
posit.addWidget(self.label_Directory, 2, 0)
self.setLayout(posit)
self.operationlongue = None
#========================================================================
@QtCore.Slot(bool)
def lancement(self, ok=False):
if self.operationlongue==None or not self.operationlongue.isRunning():
# démarre l'opération longue dans le thread
self.operationlongue = Operationlongue()
self.operationlongue.info.connect(self.label_info)
self.operationlongue.fini.connect(self.stop)
self.operationlongue.start()
#========================================================================
@QtCore.Slot(str)
def label_info(self, inputFile):
"""lancé à chaque réception d'info de progression émis par le thread"""
self.label_Directory.setText(inputFile)
QtCore.QCoreApplication.processEvents() # force le rafraichissement
#========================================================================
@QtCore.Slot(bool)
def arreter(self, ok=False):
"""pour arrêter avant la fin"""
if self.operationlongue!=None and self.operationlongue.isRunning():
self.operationlongue.arreter()
#========================================================================
@QtCore.Slot(bool)
def stop(self, fin_anormale=False):
"""Lancé quand le thread se termine"""
if fin_anormale:
# fin anticipée demandée
QtGui.QMessageBox.information(self,
u"Opération longue",
u"Arrêt demandé avant la fin!")
else:
# fin normale
QtGui.QMessageBox.information(self,
u"Opération longue",
u"Fin normale!")
#========================================================================
def closeEvent(self, event):
"""lancé à la fermeture de la fenêtre quelqu'en soit la méthode"""
# si le thread est en cours d'eécution, on l'arrête (brutalement!)
if self.operationlongue.isRunning():
self.operationlongue.terminate()
# et on accepte la fermeture de la fenêtre dans tous les cas
event.accept()
#############################################################################
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
fen = Fenetre()
fen.setAttribute(QtCore.Qt.WA_DeleteOnClose)
fen.show()
sys.exit(app.exec_()) |
Partager