Bonjour,

je suis actuellement en train de develloper une application en PyQt. Jusque là j'ai pu me débrouiller pour faire ce que je voulais, mais je n'arrive pas a lancer un calcul en tâche de fond.

En effet, j'ai un boutton en bas de barre de ma fenêtre principale, qui lance le calcul puis instancie une fenêtre censé montrer à l'utilisateur que le calcul est en cours et sa progression(voir premier bout de code). Le problème est que la fenre n'apparait qu'après la fin du calcul. Je ne sais pas comment régle mon probleme.

Voila mon code

the method used when the launch button is clicked in main window to launch the calculation and display the calculation window


Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
  def launchCalc(self):
    #retrieve the RN checked by the user
    self.getRnChoosed()
 
    #print calculation variable
    print "file: "+self.paramDic['filename']
    print "\nSite: "+str(self.paramDic['site'])
    print "\nStart Date: "+self.paramDic['startDate']
    print "\nEnd Date: "+self.paramDic['endDate']
    print "\nAerosols choisis:"+str(self.paramDic['aerosols'])
    print "\nGaz Rares choisis: "+str(self.paramDic['gazRares'])
    print "\nIodes Choisis: "+str(self.paramDic['iodes'])
    print "\nFormat d'export choisis (csv,graphes): "+str(self.paramDic['formatExport(csv,graphe)'])
    print "\nExports choisis: "+str(self.paramDic['exportsChoisis'])
 
    #check that the data are fine to launch calculation
    if len(self.paramDic['aerosols']) == 0 and len(self.paramDic['gazRares']) == 0 and len(self.paramDic['iodes']) == 0:
        QtGui.QMessageBox.warning(self, 'Donnees Invalides',"Vous devez choisir au moins un isotope pour lancer le calcul", QtGui.QMessageBox.Ok)
    elif self.resultPath == '':
        QtGui.QMessageBox.warning(self, 'Erreur',"Vous devez choisir un repertoire contenant la bibliotheque de donnees de resultats Symbiose", QtGui.QMessageBox.Ok)
    #if it's fine launch it
    else:
        self.calcWin = calcWin(self)
        self.calcWin.setWindowModality(QtCore.Qt.ApplicationModal)
        self.calcWin.show()
        launchCalc(self.paramDic,self.resultPath,self.activitiesDic)

the calcWin class


Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
class calcWin(QtGui.QWidget):
 
    def __init__(self,appelant):
        super(calcWin, self).__init__()
        self.initUI(appelant)
 
    def initUI(self,appelant):
        self.MWin = appelant
        self.step = 0
        self.VLayout = QtGui.QVBoxLayout()
        self.HLayout = QtGui.QHBoxLayout()
 
        #label
        self.label = QtGui.QLabel('Initialisation des calculs ...')
 
        #bar de progression
        self.pbar = QtGui.QProgressBar(self)
 
        #buttons
        self.btnOk = QtGui.QPushButton('Ok', self)
        self.btnOk.clicked.connect(self.close)
        self.btnOk.setEnabled(False)
 
        self.btnCancel = QtGui.QPushButton('Annuler', self)
        self.btnCancel.clicked.connect(self.cancel)
 
        #mis en place des widget et du layout
        self.VLayout.addWidget(self.label)
        self.VLayout.addWidget(self.pbar)
        self.HLayout.addWidget(self.btnOk)
        self.HLayout.addWidget(self.btnCancel)
        self.VLayout.addLayout(self.HLayout)
 
        self.setLayout(self.VLayout)
 
        #lancement des calculs et mise en forme de la fenetre
        self.setGeometry(300, 300, 280, 170)
        self.setWindowTitle('Calculs en cours')
        self.setWindowIcon(QtGui.QIcon(appelant.AbsPath+'/img/pasta.png'))
 
        #timer pour la mise a jour de la bar de progression
        self.timer = QtCore.QTimer()
        self.timer.start(1000)
        self.timer.timeout.connect(self.update)
 
    def update(self):
        self.pbar.setValue(completion)
        self.timer.start(1000)
 
 
    def cancel(self):
        self.timer.stop()
        self.close()

the calculation functions

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
def launchCalc(paramDic,resultPath,activitiesDic):
    global completion
    completion = completion + 1
    #on crée la liste de tous les RN a traiter
    listRN = paramDic['aerosols']
    listRN.extend(paramDic['gazRares'])
    listRN.extend(paramDic['iodes'])
 
    #on crée les variables bornes du calcul
    delta = datetime.timedelta(hours= 1)
    startDate = fromStringToDate(paramDic['startDate'])
    endDate = fromStringToDate(paramDic['endDate'])
 
    cinetiqueLength = len(activitiesDic[listRN[0]])
    nbPasDeTempsPeriode = int( (endDate - startDate).total_seconds() / 3600 )
    nbPasDeTempsCalcul = nbPasDeTempsPeriode - cinetiqueLength + 1
 
    #on crée le pool de worker
    p = Pool(cpu_count())
 
    # on lance la propagation de la cinetique pour chacun des RN
    time = datetime.datetime.now()
    for RN in listRN:
        completion = int( float(completion) + 100/30)
        p.map(propageCinetique,[ [CAR_to_Symb[RN], startDate + x*delta, resultPath, activitiesDic[RN] ] for x in range(nbPasDeTempsCalcul)])
 
    print datetime.datetime.now()-time
 
 
def fromStringToDate(string):
    y=int(string.split('/')[2])
    m=int(string.split('/')[1])
    d=int(string.split('/')[0])
    return datetime.datetime(y,m,d)
 
def formatDate(date):
    return date.strftime("%d-%m-%Y %H:%M:%S")
 
################################################################################
 
def propageCinetique(step):
 
    RN = step[0]
    date = step[1]
    resultPath = step[2]
    coeff = step[3]
    cinetiqueLength = len(coeff)
    tmpPath='/tmp/PASTA/'
    delta = datetime.timedelta(hours= 1)
    # stepTotal=cinetiqueLength*
    print date
 
    if os.path.isdir(tmpPath) == False:
        os.mkdir(tmpPath)
 
    Samples = []
 
    for i in range(cinetiqueLength):
        if (date + i* delta).strftime("%d-%m-%Y %H:%M:%S") in dicDates.keys():
            Samples.append(dicDates[(date + i* delta).strftime("%d-%m-%Y %H:%M:%S")])
        else:
            Samples= []
            break
 
    if Samples != []:
        for index in range(cinetiqueLength):
            if os.path.isfile(tmpPath+date.strftime("%d-%m-%Y@%H")+'.nc'):
                os.system('ncflint -O -w 1,'+ str(float(coeff[index]) * 3.6) + ' ' + tmpPath + date.strftime('%d-%m-%Y@%H') + '.nc ' +resultPath + '/' + RN + '/'+ Samples[index] +'*/Dose_allPathways.nc ' + tmpPath + date.strftime('%d-%m-%Y@%H') + '.nc ')
            else:
                os.system('ncflint -w 0,'+ str(float(coeff[index]) * 3.6) + ' ' + resultPath +'/'+ RN + '/'+ Samples[index] +'*/Dose_allPathways.nc ' + resultPath + '/' + RN + '/'+ Samples[index] +'*/Dose_allPathways.nc ' + tmpPath + date.strftime('%d-%m-%Y@%H') + '.nc ')

J'ai essayé d'utiliser la class QProcess de QtCore pour lancer le calcul en tâche de fond, mais elle de passer seulement des string en arguments de la fonction appelé, ce qui est problématique pour moi ,car mes fonctions de calculs prenne des arguments en entré.

J'èspere que quelqu'un pourra prendre le temps de se pencher sur mon problème, et je l'en remercie par avance.