コード例 #1
0
ファイル: mplayer.py プロジェクト: sxl47/learn
class Player(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.ui = None
        self.process = None
        self.init_ui()

    def init_ui(self):
        self.ui = mplayer_ui.Ui_mplayer()
        self.ui.setupUi(self)

        # 播放器初始化
        self.process = QProcess(self)
        self.process.readyReadStandardOutput.connect(self.read_player_stdout)
        time_clock = QTimer(self)
        time_clock.timeout.connect(self.time_done)

        # 播放视频
        path = '1.mp4'
        self.play_video(path)

    def time_done(self):
        self.process.write("get_time_length\n")
        self.process.write("get_time_pos\n")
        self.process.write("get_percent_pos\n")

    def read_player_stdout(self):

        while self.process.canReadLine():
            b = self.process.readLine()
            print(b)

            if b.startsWith("ANS_TIME_POSITION"):
                print(b)
            elif b.startsWith("ANS_LENGTH"):
                print(b)
            elif b.startsWith("ANS_PERCENT_POSITION"):
                print(b)

    def play_video(self, path):
        if not os.path.exists(path):
            print('not exists:{0}'.format(path))
            return
        args = QStringList()
        args << "-slave"  # 使用slave模式
        # args << "-quiet"  # 不要输出冗余信息
        args << "-wid" << QString.number(self.winId(),
                                         10)  # 将输出定位到ui下的widget窗口内
        args << "-zoom"  # 自适应窗口
        args << "-vo"
        args << "x11,xv,gl,gl2,sdl"  # 使用x11模式播放(只有这种模式下才支持23行的指定输出窗口到ui->widget)
        args << path  # 播放file_name文件
        self.process.start("MPlayer/mplayer.exe", args)  # 启动该进程,并传入参数args
コード例 #2
0
ファイル: mplayer.py プロジェクト: Ptaah/Ekd
class Mplayer(QDialog):

	REVENIR, PAS_PRECEDENT_SUIVANT, PRECEDENT_SUIVANT, CURSEUR_SUR_UNE_LIGNE,\
		CURSEUR_A_PART, PARCOURIR, PAS_PARCOURIR, LIST, RATIO = range(9)

	HAUTEUR, LARGEUR = range(2)

	def __init__(self, cheminVideo=[], taille=(250,225),
			choixWidget=(RATIO, REVENIR, PAS_PRECEDENT_SUIVANT,CURSEUR_SUR_UNE_LIGNE,PAS_PARCOURIR,LIST),
			debutFin=(0,0), cheminMPlayer=None, barreTaches=None, facteurLimitant=HAUTEUR,
			cheminParcourir=None, parent=None):

		"""widget mplayer"""
		QDialog.__init__(self, parent)

		#=== Paramètres généraux ===#
		self.setAttribute(Qt.WA_DeleteOnClose)
		self.setWindowTitle(_(u"Player vidéo"))
                #On réduit la marge pour gagner de l'espace
                self.setContentsMargins(0,0,0,0)

		self.systeme = os.name
                ### Quand EKD windows est installé, le chemin des dépendances sont ###########
                ### positionnées dans les variables d'environnement donc pas besoin de #######
                ### collecter le chemin des ces dépendances ##################################
                self.cheminMPlayer = "mplayer"

                ##############################################################################

		# liste de chemins vidéos
		if type(cheminVideo) != list :
			self.listeVideos=[cheminVideo]
		else :
			self.listeVideos = cheminVideo

		# est-ce que la vidéo est lue?
		self.estLue=False

		# est-ce que la vidéo est en pause?
		self.estEnPause=False

		self.debutFin = debutFin

		# Nom du fichier courant (le self n'est pas encore utile)
		txtParDefaut = u"Pas de fichier lu"
		if self.listeVideos.__len__()!=0:
			self.fichierCourant =  [txtParDefaut, self.listeVideos[0]]
		else: self.fichierCourant = [txtParDefaut, ""]

		# Barre des tâches de la fenêtre
		self.barreTaches = barreTaches

		# Taille de la vidéo
		self.tailleLargeur=taille[0]
		self.tailleHauteur=taille[1]

		# paramètres des boutons-icones
		iconTaille=22
		flat=1

		# Pour récupérer le temps courant depuis certains cadre
		self.temps = 0

		self.dureeTimer = 10 # temps en ms
		###############################################################################################################################

		#Pour être plus précis lors de la lecture, on prend comme unité la miliseconde. ######################
		## Il faut donc utiliser une echelle 1000 fois plus grande pour les unités du slider
		self.echelle=1000
		###############################################################################################################################

		# Permet de récupérer la durée de la vidéo depuis une instance de la classe
		# Sert dans certains cadres
		self.dureeVideo = 0

		# Chemin sur lequel peut s'ouvrir la boite de dialogue de fichier
		# associée au bouton parcourir
		self.cheminPourBoutonParcourir = cheminParcourir

		self.taille = taille

		debug("self.taille avant lecture : %s %s" % (self.taille, type(self.taille)))

		#=== Widgets ===#

		self.icone_lire=QIcon("Icones" + os.sep + "player_play.png")
		self.icone_pause=QIcon("Icones" + os.sep + "player_pause.png")
		self.icone_arret=QIcon("Icones" + os.sep + "player_stop.png")

		if Mplayer.REVENIR in choixWidget:
			self.bout_revenir = QPushButton(u"Revenir")
			self.bout_revenir.setIcon(QIcon("Icones" + os.sep + "revenir.png"))

		if Mplayer.PARCOURIR in choixWidget:
			self.bout_ouvVideo = QPushButton(u"Parcourir...")

		if Mplayer.PRECEDENT_SUIVANT in choixWidget:
			self.bout_prec = QPushButton(QIcon("Icones" + os.sep + "player_rew.png"),"")
			self.bout_prec.setIconSize(QSize(iconTaille, iconTaille))
			self.bout_prec.setFlat(flat)
			self.bout_suivant = QPushButton(QIcon("Icones" + os.sep + "player_fwd.png"),"")
			self.bout_suivant.setIconSize(QSize(iconTaille, iconTaille))
			self.bout_suivant.setFlat(flat)

		self.LISTW=False
		if Mplayer.LIST in choixWidget :
			self.LISTW = True
			self.listFichiers = QComboBox()
			self.listFichiers.hide()
			self.setListeVideo()


		self.bout_LectPause = QPushButton(self.icone_lire,"")
		self.bout_LectPause.setIconSize(QSize(iconTaille, iconTaille))
		self.bout_LectPause.setFlat(flat)

		self.bout_Arret = QPushButton(self.icone_arret,"")
		self.bout_Arret.setIconSize(QSize(iconTaille, iconTaille))
		self.bout_Arret.setFlat(flat)

		# widget qui contiendra la vidéo
		self.cibleVideo = DisplayVid(self)
		# par défaut le widget-cible est noir
		color = QColor(0, 0, 0)
		self.cibleVideo.setAutoFillBackground(True)
		self.cibleVideo.setPalette(QPalette(color))
		self.cibleVideo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
		self.cibleVideo.setFixedHeight(self.taille[1])
		self.cibleVideo.setToolTip(self.fichierCourant[0])

		#Choix de l'aspect ratio de la vidéo
                if Mplayer.RATIO in choixWidget :
                    self.conf = QGroupBox()
                    self.conf.setContentsMargins(0,0,0,0)
                    self.conf.setMinimumSize(QSize(self.tailleLargeur, 0))
                    self.conf.setObjectName("conf")
                    self.verticalLayout = QHBoxLayout(self.conf)
                    self.verticalLayout.setObjectName("verticalLayout")
                    self.choicenorm = QRadioButton(self.conf)
                    self.choicenorm.setObjectName("choicenorm")
                    self.verticalLayout.addWidget(self.choicenorm)
                    self.choicewide = QRadioButton(self.conf)
                    self.choicewide.setObjectName("choicewide")
                    self.verticalLayout.addWidget(self.choicewide)
                    self.choiceone = QRadioButton(self.conf)
                    self.choiceone.setObjectName("choiceone")
                    self.verticalLayout.addWidget(self.choiceone)
                    self.choicenorm.setText("4:3")
                    self.choicewide.setText("16:9")
                    self.choiceone.setText("w:h")
                # Checked le ratio de la vidéo
                if self.listeVideos.__len__()!=0:
                        self.changeRatio(self.listeVideos[0])
                else :
                        self.setRatio(4.0/3.0)
                        if Mplayer.RATIO in choixWidget :
                            self.choicenorm.setChecked(True)

		self.slider = QSlider(Qt.Horizontal)
		self.slider.setEnabled(True)

		self.mplayerProcess = QProcess(self)

		self.timer = QTimer(self)

		self.tempsChrono = TracerChrono()

		#=== mise-en-page/plan ===#
		mhbox = QHBoxLayout()
		vbox = QVBoxLayout()
		vbox.addWidget(self.cibleVideo)
                if Mplayer.RATIO in choixWidget :
                    vbox.addWidget(self.conf)
		hbox = QHBoxLayout()
		if Mplayer.REVENIR in choixWidget:
			hbox.addWidget(self.bout_revenir)
		if Mplayer.PARCOURIR in choixWidget:
			hbox.addWidget(self.bout_ouvVideo)
		hbox.addWidget(self.bout_LectPause)
		hbox.addWidget(self.bout_Arret)
		if Mplayer.PRECEDENT_SUIVANT in choixWidget:
			hbox.addWidget(self.bout_prec)
			hbox.addWidget(self.bout_suivant)
		hbox.addWidget(self.tempsChrono)
		if Mplayer.CURSEUR_A_PART not in choixWidget:
			hbox.addWidget(self.slider)
		vbox.addLayout(hbox)
		if Mplayer.CURSEUR_A_PART in choixWidget:
			hbox.setAlignment(Qt.AlignLeft)
			hbox = QHBoxLayout()
			hbox.addWidget(self.slider)
			vbox.addLayout(hbox)
		# Liste fichier dans combobox
		if self.LISTW :
			hbox = QHBoxLayout()
			hbox.addWidget(self.listFichiers)
			vbox.addLayout(hbox)

		mhbox.addLayout(vbox)
		self.setLayout(mhbox)

		#=== connexion des widgets à des fonctions ===#

		if Mplayer.REVENIR in choixWidget:
			self.connect(self.bout_revenir, SIGNAL('clicked()'), SLOT('close()'))
		if Mplayer.PARCOURIR in choixWidget:
			self.connect(self.bout_ouvVideo, SIGNAL('clicked()'), self.ouvrirVideo)
		if Mplayer.PRECEDENT_SUIVANT in choixWidget:
			self.connect(self.bout_prec, SIGNAL('clicked()'), self.precedent)
			self.connect(self.bout_suivant, SIGNAL('clicked()'), self.suivant)
		#Ajouté le 08/11/2009 - Liste des fichiers dans une combobox
		if self.LISTW :
			self.connect(self.listFichiers, SIGNAL('currentIndexChanged(int)'), self.changeVideo)
		self.connect(self.bout_LectPause, SIGNAL('clicked()'), self.lectPause)
		self.connect(self.bout_Arret, SIGNAL('clicked()'), self.arretMPlayer)
		self.connect(self.mplayerProcess, SIGNAL('readyReadStandardOutput()'), self.recupSortie)
		self.connect(self.mplayerProcess, SIGNAL('finished(int,QProcess::ExitStatus)'), self.finVideo)
		self.connect(self.timer, SIGNAL('timeout()'), self.sonderTempsActuel)
		self.connect(self.slider, SIGNAL('sliderMoved(int)'), self.changerTempsCurseur)
		self.connect(self.cibleVideo, SIGNAL('changeSize'), self.sizeMplayer)
                if Mplayer.RATIO in choixWidget :
                    self.connect(self.choicenorm, SIGNAL("clicked(bool)"), self.defRatio)
                    self.connect(self.choicewide, SIGNAL("clicked(bool)"), self.defRatio)
                    self.connect(self.choiceone, SIGNAL("clicked(bool)"), self.defRatio)

	def setListeVideo(self) :
		self.referenceVideo = []
		self.listFichiers.clear()
		for vid in self.listeVideos :
			self.referenceVideo.append(vid)
			self.listFichiers.addItem(os.path.basename(vid))
		if self.listeVideos.__len__() > 1 :
			self.listFichiers.show()

	def setAudio(self,au) :
		if au :
			self.cibleVideo.hide()
                        if "conf" in self.__dict__ :
			    self.conf.hide()
		else :
			self.cibleVideo.show()
                        if "conf" in self.__dict__ :
                            self.conf.show()
	def changeVideo(self, index) :
		self.arretMPlayer()
		if index >= 0 : # Condition ajoutée pour éviter une erreure de dépassement de range dans la liste.
			self.listeVideos = self.referenceVideo[index]
			self.listFichiers.setCurrentIndex(index)

	def defRatio(self, state=0) :
		if state :
			if self.choicenorm.isChecked() :
				self.setRatio(4.0/3.0)
			if self.choicewide.isChecked() :
				self.setRatio(16.0/9.0)
			if self.choiceone.isChecked() :
				try :
					dim=getVideoSize(unicode(self.listeVideos[0]))
					self.setRatio(dim[0]/dim[1])
				except :
					None
			self.defRatio()
		else :
			self.adjustSize()

	def setRatio(self,ratio) :
		self.ratio = ratio
		self.sizeMplayer()

	def changeRatio(self,video) :
		rv = getVideoRatio(video)
		if rv[0]==0.0 and type(rv[1])==float :
			rat = rv[1]
		else :
			rat = rv[0]

		if rat > 1.7 :
                        if "choicewide" in self.__dict__ :
                            self.choicewide.setChecked(True)
			self.setRatio(16.0/9.0)
		elif rat > 1.3 and rat <= 1.7 :
                        if "choicenorm" in self.__dict__ :
                            self.choicenorm.setChecked(True)
			self.setRatio(4.0/3.0)
		elif rat < 1.3 and rat != 0.0 :
                        if "choiceone" in self.__dict__ :
                            self.choiceone.setChecked(True)
			dim=getVideoSize(video)
			self.setRatio(dim[0]/dim[1])
		else :
                        if "choicenorm" in self.__dict__ :
                            self.choicenorm.setChecked(True)
			self.setRatio(4.0/3.0)

	def sizeMplayer(self) :
		self.cibleVideo.setFixedHeight(int(self.cibleVideo.width()/self.ratio))

	def ouvrirVideo(self):
		"""Ouverture de la boîte de dialogue de fichiers"""
		txt = u"Fichiers vidéo"
		if self.cheminPourBoutonParcourir:
			chemin = self.cheminPourBoutonParcourir

		else:
			try:
				chemin = EkdConfig.get('general','video_input_path').decode("UTF8")
			except:
				chemin = os.path.expanduser('~')

		liste=QFileDialog.getOpenFileNames(None, u"Ouvrir", chemin, "%s (*.avi *.mpg *.mpeg *.mjpeg *.flv *.mp4 *.ogg *.vob *.mov *.wmv *.3gp *.h264)\n*" %txt)
		if not liste: return
		self.listeVideos = liste
		self.changeRatio(unicode(self.listeVideos[0]))

		chemin = unicode(self.listeVideos[0])
		EkdConfig.set('general','video_input_path',os.path.dirname(chemin).encode("UTF8"))

	def setVideos(self, videos) :
		'''Définie proprement la liste des vidéos à jouer'''
		if type(videos) != list :
			self.listeVideos = [videos]
		else :
			self.listeVideos = videos
		if self.LISTW and videos.__len__() > 1 :
			self.setListeVideo()
		elif self.LISTW :
			self.listFichiers.hide()

	def demarrerMPlayer(self):
		"""démarrage de mplayer avec les arguments choisis"""
		if self.estLue:
			return True

		args = QStringList()	# Liste Qt qui contiendra les options de mplayer
					# Ajout d'options à liste: args << "-option"

		# mplayer fonctionnera comme un terminal dans ce script
		args << "-slave"
		# on ne veut pas avoir des commentaires sans grand intérêt
		args << "-quiet"

		# Sous linux, aucun driver n'a été nécessaire et pas de manip pour Wid :)
		if self.systeme=='posix':
			# try - except?
			# la fenêtre de mplayer restera attaché à la fenêtre
			# wid prend en valeur le nombre identifiant le widget (celui qui contiendra la vidéo)
			args << "-wid" << QString.number(self.cibleVideo.winId()) # Objet QString car args est une liste de ch de caractères
			settings = QSettings()
			videoOutput = settings.value("vo", QVariant('')).toString()
			if videoOutput:
				args << '-vo' << videoOutput

		# Sous windows
		else:
			# reinterpret_cast<qlonglong> obligatoire, winId() ne se laissant pas convertir gentiment ;)
			args << "-wid" << self.cibleVideo.winId().__hex__()
			args << "-vo" << "directx:noaccel"
			#args << "-vo" << "gl" # alternative

		# chemin de la vidéo
		args << self.listeVideos

		if PYQT_VERSION_STR >= "4.1.0":
			# mode de canal: on fusionne le canal de sortie normal (stdout) et celui des erreurs (stderr)
			self.mplayerProcess.setProcessChannelMode(QProcess.MergedChannels)
		# démarrage de mplayer (en tenant compte des arguments définis ci-dessus)
		# comme un nouveau processus
		self.mplayerProcess.start(self.cheminMPlayer, args)
		# au cas où mplayer ne démarrerait pas au bout de 3 sec (ex. problème de codec)
		if not self.mplayerProcess.waitForStarted(3000):
			QMessageBox.critical(self, u"Avertissement", u"Bogue au lancement de la vidéo avec mplayer")
			return False

		# donne le temps toutes les x secondes
		self.timer.start(self.dureeTimer)

		self.estLue = True

		return True

	def recupSortie(self):
		"""récupère les lignes d'information émises par QProcess (mplayerProcess) et en tire les conséquences"""
		while self.mplayerProcess.canReadLine(): # renvoie True si une ligne complète peut être lue à partir du système
			# stocker l'ensemble des bits d'une ligne
			tampon=QByteArray(self.mplayerProcess.readLine()) # readline: lit une ligne ascii à partir du système

			# On vérifie si on a eu des réponses
			if tampon.startsWith("Playing"):
				# On récupère les infos de base ('$ mplayer -input cmdlist' pour avoir la liste complète - file:///usr/share/doc/mplayer-doc/tech/slave.txt.gz pour plus de détails)
				self.mplayerProcess.write("get_video_resolution\n") # récupère la résolution de la vidéo
				self.mplayerProcess.write("get_time_length\n")
				# Nouveau fichier chargé -> on récupère son nom
				ind = tampon.length() - 2 # suppression du '.' à la fin
				tampon.remove(ind,ind)
				tampon.remove(0, 8) # vire Playing
				tampon.replace(QByteArray("\n"), QByteArray(""))
				tampon.replace(QByteArray("\r"), QByteArray(""))
				try:
					# Tour de passe-passe pour ne pas avoir de problème d'accents

					# Condition pour détection windows
					if os.name == 'nt':
						self.fichierCourant[1]=unicode(QString(tampon))
					# Condition pour détection Linux ou MacOSX
					elif os.name in ['posix', 'mac']:
						self.fichierCourant[1]=unicode(QString(tampon)).encode("Latin1").decode("UTF8")
				except UnicodeEncodeError, e:
					debug(e)
					self.fichierCourant[1]="?"
				self.cibleVideo.setToolTip(self.fichierCourant[1])
				if self.barreTaches is not None:
					self.barreTaches.showMessage(self.fichierCourant[1])

			# réponse à get_video_resolution : ANS_VIDEO_RESOLUTION='<width> x <height>'
			if tampon.startsWith("ANS_VIDEO_RESOLUTION"): # retourne True si l'ensemble de bits démarre avec "..."
				debug("tampon : %s" % tampon) # ex. -> ANS_VIDEO_RESOLUTION='352 x 288'
				tampon.remove(0, 21) # suppression des 21 1er caract -> '352 x 288'
				tampon.replace(QByteArray("'"), QByteArray("")) # -> 352 x 288
				tampon.replace(QByteArray(" "), QByteArray("")) # -> 352x288
				tampon.replace(QByteArray("\n"), QByteArray("")) # -> 352x288 # retour chariot unix
				tampon.replace(QByteArray("\r"), QByteArray("")) # -> 352x288 # retour chariot windows
				#print "-----tampon.indexOf('x') :", tampon.indexOf('x'), type(tampon.indexOf('x'))
				sepIndex = tampon.indexOf('x') # récupère la position de 'x' # 3 <type 'int'>
				#print "-----tampon.left(sepIndex).toInt():", tampon.left(sepIndex).toInt(), type(tampon.left(sepIndex).toInt())
				resX = tampon.left(sepIndex).toInt()[0] # -> 352 # (352, True) <type 'tuple'>
				#print "-----tampon.mid(sepIndex+1).toInt() :", tampon.mid(sepIndex+1).toInt(), type(tampon.mid(sepIndex+1).toInt())
				resY = tampon.mid(sepIndex+1).toInt()[0] # -> 288 # (288, True) <type 'tuple'>

				# on définit les nouvelles dimensions de l'image du widget-mplayer.
				# try pour éviter les bogues sur les fichiers audio (sans dimension d'image)!!!
				#try:
				if resX!=0 or resY!=0:
					debug( "ratio : %s - %s" % (self.ratio, type(self.ratio)))
				else:
					debug("fichier audio")

			# réponse à get_time_length : ANS_LENGTH=xx.yy
			elif tampon.startsWith("ANS_LENGTH"):
				debug("tampon : %s" % tampon) # -> ANS_LENGTH=279.38
				tampon.remove(0, 11) # vire ANS_LENGTH=
				tampon.replace(QByteArray("'"), QByteArray(""))
				tampon.replace(QByteArray(" "), QByteArray(""))
				tampon.replace(QByteArray("\n"), QByteArray(""))
				tampon.replace(QByteArray("\r"), QByteArray("")) # -> 279.38
				#print "-----tampon.toFloat() :", tampon.toFloat(), type(tampon.toFloat())
				tempsMax = tampon.toFloat()[0] # (279.3800048828125, True) <type 'tuple'>
				self.dureeVideo = tempsMax
				## Modifié le 28/05/2009 : On augmente la précision du slider
				#self.slider.setMaximum(tempsMax) # déf du domaine de valeur du curseur
				self.slider.setMaximum(tempsMax*self.echelle)

				# ATTENTION J'AI COMMENTE CETTE LIGNE !!!
				#self.slider.setMaximum(tempsMax)

			# réponse à get_time_pos : ANS_TIME_POSITION=xx.y
			elif tampon.startsWith("ANS_TIME_POSITION"):
				#print "tampon :",tampon # -> ANS_TIME_POSITION=1.4 (temps courant)
				tampon.remove(0, 18) # vire ANS_TIME_POSITION=
				tampon.replace(QByteArray("'"), QByteArray(""))
				tampon.replace(QByteArray(" "), QByteArray(""))
				tampon.replace(QByteArray("\n"), QByteArray(""))
				tampon.replace(QByteArray("\r"), QByteArray(""))
				#print "-----tampon.toFloat() :", tampon.toFloat(), type(tampon.toFloat())
				tempsCourant = tampon.toFloat()[0] # (1.3999999761581421, True) <type 'tuple'>
				# récupération du temps courant: utile dans certains cadres
				self.temps = tempsCourant
				# Programmer un arrêt. Utile pour les aperçus
				temps = float("%.1f" %self.temps)
				if self.debutFin!=(0,0) and self.debutFin[1]==temps:
					self.arretMPlayer()
					return
				self.slider.setValue(tempsCourant*self.echelle)
				#############################################################################
				self.changerTempsChrono(tempsCourant) # modifier le chrono du bouton
コード例 #3
0
class FrD_NukeBatchRender(QtGui.QMainWindow, form_class):
    def __init__(self, parent=None):

        QtGui.QMainWindow.__init__(self, parent)

        self.setupUi(self)
        self.setWindowTitle('FrD Nuke Batch Render' + PROGRAM_VERSION)
        self.output_LW.setEnabled(0)
    # ============================ STYLE ======================= #
        # Progress Bar Style
        PB_STYLE = """
        QProgressBar
        {
            border: 2px solid grey;
            border-radius: 5px;
            text-align: center;
        }

        QProgressBar::chunk
        {
            background-color: #d7801a;
            width: 3px;
            margin: 1.5px;
        }
        """
        # self.PB.setStyleSheet(PB_STYLE)

        # QMenuBar Style
        MB_STYLE = """
        QMenuBar::item
        {
            background: transparent;
        }

        QMenuBar::item:selected
        {
            background: background-color: rgb(49,49,49);
            border: 1px solid #000;
        }

        QMenuBar::item:pressed
        {
            background: #444;
            border: 1px solid #000;
            background-color: QLinearGradient(
                x1:0, y1:0,
                x2:0, y2:1,
                stop:1 #212121,
                stop:0.4 #343434/*,
                stop:0.2 #343434,
                stop:0.1 #ffaa00*/
            );
            margin-bottom:-1px;
            padding-bottom:1px;
        }

        """
        self.menuFiles.setStyleSheet(MB_STYLE)
    # ============================ STYLE ======================= #

        # Enable Drah and Drop
        self.Queue_TW.setAcceptDrops(True)
        # Set up handlers for the TableWidget
        self.Queue_TW.dragEnterEvent = self.twDragEnterEvent
        self.Queue_TW.dragMoveEvent = self.twDragMoveEvent
        self.Queue_TW.dropEvent = self.twDropEvent

        # Size of Table Columns
        self.Queue_TW.setColumnWidth(0, 250)
        self.Queue_TW.setColumnWidth(1, 300)
        self.Queue_TW.setColumnWidth(2, 100)
        self.Queue_TW.setColumnWidth(3, 100)
        self.Queue_TW.setColumnWidth(4, 310)
        self.Queue_TW.setColumnWidth(5, 110)

        # operation ALL
        self.Clear_BN.clicked.connect(self.ClearQueue)
        self.Update_BN.clicked.connect(self.UpdateQueue)
        # Render
        self.Render_BN.clicked.connect(self.NBR_render)

    # ============ Drag and Drop Event) ============ #
    def twDragEnterEvent(self, event):
        if event.mimeData().hasUrls:
            event.accept()
        else:
            event.ignore()

    def twDragMoveEvent(self, event):
        if event.mimeData().hasUrls:
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()
        else:
            event.ignore()

    def twDropEvent(self, event):
        if event.mimeData().hasUrls:
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()
            links = []
            for url in event.mimeData().urls():
                links.append(str(url.toLocalFile()))
            # print links
            self.nukeProjDropped(links)
        else:
            event.ignore()
    # ============  Drag and Drop Ends  ============ #
    # ============ Clear and Update All ============ #

    def NBR_askMsg(self, title, text):
        qmsgBox = QtGui.QMessageBox()
        qmsgBox.setStyleSheet('QMessageBox {background-color: #333; font-size: 12pt; font-family: Trebuchet MS}\nQLabel{color:white;}')  # 585858
        return QtGui.QMessageBox.question(qmsgBox, title, text, QtGui.QMessageBox.Yes | QtGui.QMessageBox.Cancel)  # | QtGui.QMessageBox.No

    def ClearQueue(self):
        global folderQueue
        if self.Queue_TW.rowCount() > 0:
            if (self.NBR_askMsg('Clear Render Queue', 'Are you sure you want to clear the whole Render Queue?') == QtGui.QMessageBox.Yes):
                self.Queue_TW.setRowCount(0)
                folderQueue = []
                QtGui.QApplication.processEvents()

    def UpdateQueue(self):
        global folderQueue
        for project in xrange(len(folderQueue)):
            pass
    # ========== Clear and Update All Ends ========== #

    def nukeProjDropped(self, arg):
        global folderQueue
        appendedList = []

        for url in sorted(arg):
            if os.path.exists(url) and os.path.isfile(url) and url.lower().endswith('.nk'):
                if url in folderQueue:
                    pass
                else:
                    appendedList.append(url)
                    folderQueue.append(url)
                    # Add table row
                    rowPosition = self.Queue_TW.rowCount()
                    self.Queue_TW.insertRow(rowPosition)
                    # get All Write Node from .nk
                    # QProcess for nuke
                    self.nukeProcess = QProcess(self)
                    self.nukeProcess.setProcessChannelMode(QProcess.MergedChannels)
                    args = self.createCmdArg(str(url))
                    self.nukeProcess.start(NUKE_EXE, args)
                    # For debug: read output lines
                    self.nukeProcess.readyRead.connect(self.NBR_debug)
                    self.nukeProcess.waitForFinished()
                    self.nukeProcess.close()
                    # Add row and info to table
                    self.NBR_createCheckBoxItemTableWidget(rowPosition, 0, os.path.splitext(os.path.basename(url))[0])
                    # Get the write nodes from text files (D:/Temp/nukeBatch)
                    layout = QtGui.QVBoxLayout()
                    layout.setAlignment(QtCore.Qt.AlignLeft)
                    with open("D:\\Temp\\nukeBatch\\" + os.path.basename(url) + ".txt", "r") as ins:
                        bframe = False
                        bCount = 0
                        for line in ins:
                            if 'FrameRange:' in line:
                                bframe = True
                                continue
                            if (bframe is False):
                                item = QtGui.QCheckBox(str(line).strip())
                                item.setChecked(True)
                                item.setFont(QtGui.QFont('meiryo', 9))
                                layout.addWidget(item)
                            elif (bframe is True):
                                self.NBR_createEditTextItemTableWidget(rowPosition, 2 + bCount, int(str(line).strip()))
                                bCount += 1

                    cellWidget = QtGui.QWidget()
                    cellWidget.setLayout(layout)
                    self.Queue_TW.setCellWidget(rowPosition, 1, cellWidget)
        self.Queue_TW.resizeRowsToContents()
        self.Queue_TW.scrollToBottom()
        QtGui.QApplication.processEvents()

    def createCmdArg(self, nk):  # nk = url
        return ["-ti", CHECKING_NK, nk]

    def createCmdArg2(self, nk, start, end, wnode=[]):
        return ["-ti", RENDER_NK, nk, wnode, start, end]

    def NBR_debug(self):
        while (self.nukeProcess.canReadLine()):
            print (str(self.nukeProcess.readLine()))

    def NBR_createCheckBoxItemTableWidget(self, row, col, text, color='#4c4c4c'):
        layout = QtGui.QVBoxLayout()
        layout.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft)

        item = QtGui.QCheckBox(text)
        item.setChecked(True)
        item.setFont(QtGui.QFont('meiryo', 9))

        layout.addWidget(item)
        cellWidget = QtGui.QWidget()
        cellWidget.setStyleSheet('color:white; background-color:' + color)

        cellWidget.setLayout(layout)
        self.Queue_TW.setCellWidget(row, col, cellWidget)
        # self.Queue_TW.setItem(row, 0, QtGui.QTableWidgetItem(str(text)))

    def NBR_createEditTextItemTableWidget(self, row, col, text, color='#4c4c4c'):
        layout = QtGui.QVBoxLayout()
        layout.setAlignment(QtCore.Qt.AlignCenter)

        item = QtGui.QSpinBox()
        item.setMaximum(9999)
        item.setValue(text)
        item.setFont(QtGui.QFont('meiryo', 9))

        layout.addWidget(item)
        cellWidget = QtGui.QWidget()
        cellWidget.setStyleSheet('color:white; background-color:' + color)

        cellWidget.setLayout(layout)
        self.Queue_TW.setCellWidget(row, col, cellWidget)

    def NBR_getCellData(self, row, col, key):
        cellDict = {}
        target = self.Queue_TW.cellWidget(row, col)
        if target:
            lay = target.layout()
            if lay:
                for k in xrange(lay.count()):
                    w = lay.itemAt(k).widget()

                    if isinstance(w, QtGui.QCheckBox):
                        cellDict[key] = w.checkState()  # 0 false, > 0 true
                    elif isinstance(w, QtGui.QSpinBox):
                        cellDict[key] = w.value()
        return cellDict

    def NBR_getCellNodeData(self, row, col):
        target = self.Queue_TW.cellWidget(row, col)
        cellUserInputList = []
        if target:
            lay = target.layout()
            if lay:
                for k in xrange(lay.count()):
                    w = lay.itemAt(k).widget()

                    if isinstance(w, QtGui.QCheckBox):
                        cellUserInputList.append([str(w.text()), w.checkState()])
                    else:
                        cellUserInputList.append(-1)
        return cellUserInputList

    def NBR_render(self):
        global folderQueue
        for nk in xrange(len(folderQueue)):
            renderNode = []
            # proj = os.path.splitext(os.path.basename(folderQueue[nk]))[0]
            projDict = self.NBR_getCellData(nk, 0, 'Project')
            if int(projDict['Project']) > 0:
                nodeArr = self.NBR_getCellNodeData(nk, 1)
                startDict = self.NBR_getCellData(nk, 2, 'Start')
                endDict = self.NBR_getCellData(nk, 3, 'End')
                # Write nodes loop
                for node in xrange(len(nodeArr)):
                    if nodeArr[node][1] > 0:  # get each node check state (0/2), selected write node (render)
                        renderNode.append(nodeArr[node][0].split(":")[0])
                # Debug
                print str(renderNode)
                # print nodeArr
                self.nukeProcess = QProcess(self)    # QProcess for nuke
                print nodeArr[node][0].split(":")[0]  # get each node from array
                self.nukeProcess.setProcessChannelMode(QProcess.MergedChannels)
                args = self.createCmdArg2(str(folderQueue[nk]), renderNode, startDict['Start'], endDict['End'])
                self.nukeProcess.start(NUKE_EXE, str(args))
                self.nukeProcess.readyRead.connect(self.NBR_debug)
                self.nukeProcess.waitForFinished()
                self.nukeProcess.close()
コード例 #4
0
ファイル: pylint.py プロジェクト: tonal/KhtEditor
class PyLint(Plugin, QObject):
    """ PyLint Plugin """
    capabilities = ['toolbarHook']
    __version__ = '0.5'
    thread = None

    def do_toolbarHook(self, widget):
        """ Hook to install the pylint toolbar button"""
        widget.addAction('PyLint', self.do_pylint)

    @pyqtSlot()
    def do_pylint(self):
        """ Launch the lint process and create the result window """
        print 'do_pylint'

        self.pylint_pross = QProcess()
        self.pylint_pross.setProcessChannelMode(QProcess.MergedChannels)
        self.pylint_pross.setWorkingDirectory( \
            os.path.dirname(str(self.parent.editor.filename)))
        self.pylint_pross.setReadChannel(QProcess.StandardOutput)

        self.connect(self.pylint_pross, \
            SIGNAL('finished(int)'), \
            self.finished)
        self.connect(self.pylint_pross, \
            SIGNAL('readyReadStandardOutput()'), \
            self.handle_stdout)
        self.connect(self.pylint_pross, \
            SIGNAL('readyReadStandardError()'), \
            self.handle_stderr)
        if (self.pylint_pross.start("pylint", \
                [self.parent.editor.filename,])):
            print 'Cannot start process'

        self.win = ResultWin()
        self.win.setWindowTitle("PyLint Results :" \
            + os.path.basename(str(self.parent.editor.filename)))
        self.win.show()
        if isMAEMO:
            self.win.setAttribute(Qt.WA_Maemo5ShowProgressIndicator, True)

        self.win.connect(self.win.list_view, \
            SIGNAL('doubleClicked(const QModelIndex&)'), \
            self.goto_line)

        self.pylint_pross.waitForStarted()

    def finished(self, _):
        """ Call back called when lint end """
        if isMAEMO:
            self.win.setAttribute(Qt.WA_Maemo5ShowProgressIndicator, False)

    def handle_stdout(self):
        """
        Private slot to handle the readyReadStdout
        signal of the pylint process.
        """
        result_list = []
        #regex = QRegExp('(\w)\S*:\S*(\d*):.*: (.*)')
        regex = QRegExp('(\w)\s*:\s*(\d*):(.*)')
        regex_score = \
            QRegExp('.*at.(\d.\d*)/10.*')
        while self.pylint_pross and self.pylint_pross.canReadLine():
            result = unicode(self.pylint_pross.readLine())
            if result != None:
                pos = 0
                while True:
                    pos = regex.indexIn(result, pos)
                    if pos < 0:
                        if regex_score.indexIn(result, 0) >= 0:
                            self.win.setWindowTitle( \
                                "PyLint Results :" \
                                + str(regex_score.cap(1)) \
                                + ':'
                                + os.path.basename(str(self.parent.editor.filename)))
                        break
                    result_list.append(
                        (regex.cap(1), regex.cap(2), regex.cap(3)))
                    #print 'Append : ',(regex.cap(1), regex.cap(2), regex.cap(3))
                    pos = pos + regex.matchedLength()

        if len(result_list) > 0:
            self.win.append_results(result_list)

    def goto_line(self, index):
        """ Callback called when a lint result is double clicked """
        line = int(self.win.list_model.items[index.row()][1])
        self.parent.do_gotoLine(line)

    def handle_stderr(self):
        """
        Private slot to handle the readyReadStderr
        signal of the pylint process. Currently not
        managed
        """
        print 'error stderr'
コード例 #5
0
class SvnChangeListsDialog(QDialog, Ui_SvnChangeListsDialog):
    """
    Class implementing a dialog to browse the change lists.
    """
    def __init__(self, vcs, parent=None):
        """
        Constructor
        
        @param vcs reference to the vcs object
        @param parent parent widget (QWidget)
        """
        QDialog.__init__(self, parent)
        self.setupUi(self)
        
        self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False)
        self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True)
        
        self.process = None
        self.vcs = vcs
        
        self.rx_status = \
            QRegExp('(.{8,9})\\s+([0-9-]+)\\s+([0-9?]+)\\s+(\\S+)\\s+(.+)\\s*')
            # flags (8 or 9 anything), revision, changed rev, author, path
        self.rx_status2 = \
            QRegExp('(.{8,9})\\s+(.+)\\s*')
            # flags (8 or 9 anything), path
        self.rx_changelist = \
            QRegExp('--- \\S+ .([\\w\\s]+).:\\s+')
            # three dashes, Changelist (translated), quote,
            # changelist name, quote, :
    
    @pyqtSignature("QListWidgetItem*, QListWidgetItem*")
    def on_changeLists_currentItemChanged(self, current, previous):
        """
        Private slot to handle the selection of a new item.
        
        @param current current item (QListWidgetItem)
        @param previous previous current item (QListWidgetItem)
        """
        self.filesList.clear()
        if current is not None:
            changelist = unicode(current.text())
            if changelist in self.changeListsDict:
                self.filesList.addItems(sorted(self.changeListsDict[changelist]))
    
    def start(self, path):
        """
        Public slot to populate the data.
        
        @param path directory name to show change lists for (string)
        """
        self.changeListsDict = {}
        
        self.filesLabel.setText(self.trUtf8("Files (relative to %1):").arg(path))
        
        self.errorGroup.hide()
        self.intercept = False
        
        self.path = path
        self.currentChangelist = ""
        
        self.process = QProcess()
        self.process.finished.connect(self.__procFinished)
        self.process.readyReadStandardOutput.connect(self.__readStdout)
        self.process.readyReadStandardError.connect(self.__readStderr)
        
        args = []
        args.append('status')
        self.vcs.addArguments(args, self.vcs.options['global'])
        self.vcs.addArguments(args, self.vcs.options['status'])
        if '--verbose' not in self.vcs.options['global'] and \
           '--verbose' not in self.vcs.options['status']:
            args.append('--verbose')
        if isinstance(path, list):
            self.dname, fnames = self.vcs.splitPathList(path)
            self.vcs.addArguments(args, fnames)
        else:
            self.dname, fname = self.vcs.splitPath(path)
            args.append(fname)
        
        self.process.setWorkingDirectory(self.dname)
        
        self.process.start('svn', args)
        procStarted = self.process.waitForStarted()
        if not procStarted:
            self.inputGroup.setEnabled(False)
            self.inputGroup.hide()
            KQMessageBox.critical(self,
                self.trUtf8('Process Generation Error'),
                self.trUtf8(
                    'The process %1 could not be started. '
                    'Ensure, that it is in the search path.'
                ).arg('svn'))
        else:
            self.inputGroup.setEnabled(True)
            self.inputGroup.show()
    
    def __finish(self):
        """
        Private slot called when the process finished or the user pressed
        the button.
        """
        if self.process is not None and \
           self.process.state() != QProcess.NotRunning:
            self.process.terminate()
            QTimer.singleShot(2000, self.process.kill)
            self.process.waitForFinished(3000)
        
        self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True)
        self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False)
        self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
        
        self.inputGroup.setEnabled(False)
        self.inputGroup.hide()
        
        if len(self.changeListsDict) == 0:
            self.changeLists.addItem(self.trUtf8("No changelists found"))
            self.buttonBox.button(QDialogButtonBox.Close).setFocus(Qt.OtherFocusReason)
        else:
            self.changeLists.addItems(sorted(self.changeListsDict.keys()))
            self.changeLists.setCurrentRow(0)
            self.changeLists.setFocus(Qt.OtherFocusReason)
    
    def on_buttonBox_clicked(self, button):
        """
        Private slot called by a button of the button box clicked.
        
        @param button button that was clicked (QAbstractButton)
        """
        if button == self.buttonBox.button(QDialogButtonBox.Close):
            self.close()
        elif button == self.buttonBox.button(QDialogButtonBox.Cancel):
            self.__finish()
        
    def __procFinished(self, exitCode, exitStatus):
        """
        Private slot connected to the finished signal.
        
        @param exitCode exit code of the process (integer)
        @param exitStatus exit status of the process (QProcess.ExitStatus)
        """
        self.__finish()
        
    def __readStdout(self):
        """
        Private slot to handle the readyReadStandardOutput signal.
        
        It reads the output of the process, formats it and inserts it into
        the contents pane.
        """
        if self.process is not None:
            self.process.setReadChannel(QProcess.StandardOutput)
            
            while self.process.canReadLine():
                s = unicode(self.process.readLine(),
                            Preferences.getSystem("IOEncoding"),
                            'replace')
                if self.currentChangelist != "" and self.rx_status.exactMatch(s):
                    file = unicode(self.rx_status.cap(5)).strip()
                    filename = file.replace(self.path + os.sep, "")
                    if filename not in self.changeListsDict[self.currentChangelist]:
                        self.changeListsDict[self.currentChangelist].append(filename)
                elif self.currentChangelist != "" and self.rx_status2.exactMatch(s):
                    file = unicode(self.rx_status2.cap(2)).strip()
                    filename = file.replace(self.path + os.sep, "")
                    if filename not in self.changeListsDict[self.currentChangelist]:
                        self.changeListsDict[self.currentChangelist].append(filename)
                elif self.rx_changelist.exactMatch(s):
                    self.currentChangelist = unicode(self.rx_changelist.cap(1))
                    if self.currentChangelist not in self.changeListsDict:
                        self.changeListsDict[self.currentChangelist] = []
        
    def __readStderr(self):
        """
        Private slot to handle the readyReadStandardError signal.
        
        It reads the error output of the process and inserts it into the
        error pane.
        """
        if self.process is not None:
            self.errorGroup.show()
            s = QString(self.process.readAllStandardError())
            self.errors.insertPlainText(s)
            self.errors.ensureCursorVisible()
        
    def on_passwordCheckBox_toggled(self, isOn):
        """
        Private slot to handle the password checkbox toggled.
        
        @param isOn flag indicating the status of the check box (boolean)
        """
        if isOn:
            self.input.setEchoMode(QLineEdit.Password)
        else:
            self.input.setEchoMode(QLineEdit.Normal)
        
    @pyqtSignature("")
    def on_sendButton_clicked(self):
        """
        Private slot to send the input to the subversion process.
        """
        input = self.input.text()
        input += os.linesep
        
        if self.passwordCheckBox.isChecked():
            self.errors.insertPlainText(os.linesep)
            self.errors.ensureCursorVisible()
        else:
            self.errors.insertPlainText(input)
            self.errors.ensureCursorVisible()
        
        self.process.write(input)
        
        self.passwordCheckBox.setChecked(False)
        self.input.clear()
        
    def on_input_returnPressed(self):
        """
        Private slot to handle the press of the return key in the input field.
        """
        self.intercept = True
        self.on_sendButton_clicked()
        
    def keyPressEvent(self, evt):
        """
        Protected slot to handle a key press event.
        
        @param evt the key press event (QKeyEvent)
        """
        if self.intercept:
            self.intercept = False
            evt.accept()
            return
        QDialog.keyPressEvent(self, evt)
コード例 #6
0
ファイル: pylint.py プロジェクト: khertan/KhtEditor
class PyLint(Plugin, QObject):
    """ PyLint Plugin """
    capabilities = ['toolbarHook']
    __version__ = '0.5'
    thread = None
    
    def do_toolbarHook(self, widget):
        """ Hook to install the pylint toolbar button"""
        widget.addAction('PyLint', self.do_pylint)
        
        
    @pyqtSlot()
    def do_pylint(self):
        """ Launch the lint process and create the result window """
        print 'do_pylint'

        self.pylint_pross = QProcess()
        self.pylint_pross.setProcessChannelMode(QProcess.MergedChannels)
        self.pylint_pross.setWorkingDirectory( \
            os.path.dirname(str(self.parent.editor.filename)))
        self.pylint_pross.setReadChannel(QProcess.StandardOutput)

        self.connect(self.pylint_pross, \
            SIGNAL('finished(int)'), \
            self.finished)
        self.connect(self.pylint_pross, \
            SIGNAL('readyReadStandardOutput()'), \
            self.handle_stdout)
        self.connect(self.pylint_pross, \
            SIGNAL('readyReadStandardError()'), \
            self.handle_stderr)
        if (self.pylint_pross.start("pylint", \
                [self.parent.editor.filename,])):
            print 'Cannot start process'

        self.win = ResultWin()
        self.win.setWindowTitle("PyLint Results :" \
            + os.path.basename(str(self.parent.editor.filename)))
        self.win.show()
        if isMAEMO:
            self.win.setAttribute(Qt.WA_Maemo5ShowProgressIndicator, True)
            
        self.win.connect(self.win.list_view, \
            SIGNAL('doubleClicked(const QModelIndex&)'), \
            self.goto_line)

        self.pylint_pross.waitForStarted()
        
    def finished(self, _):
        """ Call back called when lint end """
        if isMAEMO:
            self.win.setAttribute(Qt.WA_Maemo5ShowProgressIndicator, False)
            
    def handle_stdout(self):
        """
        Private slot to handle the readyReadStdout
        signal of the pylint process.
        """
        result_list = []
        #regex = QRegExp('(\w)\S*:\S*(\d*):.*: (.*)')
        regex = QRegExp('(\w)\s*:\s*(\d*):(.*)')
        regex_score = \
            QRegExp('.*at.(\d.\d*)/10.*')
        while self.pylint_pross and self.pylint_pross.canReadLine():
            result = unicode(self.pylint_pross.readLine())
            if result != None:
                pos = 0
                while True:
                    pos = regex.indexIn(result, pos)
                    if pos < 0:
                        if regex_score.indexIn(result, 0) >= 0:
                            self.win.setWindowTitle( \
                                "PyLint Results :" \
                                + str(regex_score.cap(1)) \
                                + ':'                                
                                + os.path.basename(str(self.parent.editor.filename)))
                        break
                    result_list.append((regex.cap(1), regex.cap(2), regex.cap(3)))
                    #print 'Append : ',(regex.cap(1), regex.cap(2), regex.cap(3))
                    pos = pos + regex.matchedLength()
                    
        if len(result_list)>0:
            self.win.append_results(result_list)
        
    def goto_line(self, index):
        """ Callback called when a lint result is double clicked """
        line = int(self.win.list_model.items[index.row()][1])
        self.parent.do_gotoLine(line)
        
    def handle_stderr(self):
        """
        Private slot to handle the readyReadStderr
        signal of the pylint process. Currently not
        managed
        """
        print 'error stderr'
コード例 #7
0
class CFDSTUDYGUI_QProcessDialog(QDialog, Ui_CFDSTUDYGUI_QProcessDialog):
    """
    Advanced dialog.
    """
    def __init__(self, parent, title, cmd_list, obj_directory="", start_directory=""):
        """
        Constructor
        """
        QDialog.__init__(self, parent)

        Ui_CFDSTUDYGUI_QProcessDialog.__init__(self)
        self.setupUi(self)
        self.setWindowTitle(title)
        self.pushButton.setEnabled(False)

        if start_directory != None and start_directory != "":
            os.chdir(start_directory)

        self.objBr = None
        if obj_directory != None and obj_directory != "":
            self.objBr = obj_directory

        self.proc = QProcess()
        #env = QProcessEnvironment().systemEnvironment()
        #self.proc.setProcessEnvironment(env)

        self.connect(self.proc, SIGNAL('readyReadStandardOutput()'), self.__readFromStdout)
        self.connect(self.proc, SIGNAL('readyReadStandardError()'),  self.__readFromStderr)
        self.procErrorFlag = False

        self.cmd_list = cmd_list
        self.cmd = self.cmd_list.pop(0)
        cursor = QCursor(Qt.BusyCursor)
        QApplication.setOverrideCursor(cursor)
        self.__process()


    def __process(self):
        if self.proc.exitStatus() == QProcess.NormalExit and not self.procErrorFlag:
            self.proc.start(self.cmd)
            if self.cmd_list:
                self.cmd = self.cmd_list.pop(0)
                self.connect(self.proc,
                             SIGNAL('finished(int, QProcess::ExitStatus)'),
                             self.__process)
            else:
                self.connect(self.proc,
                             SIGNAL('finished(int, QProcess::ExitStatus)'),
                             self.__finished)


    def __readFromStdout(self):
        """
        Private slot to handle the readyReadStandardOutput signal of the process.
        """
        if self.proc is None:
            return
        self.proc.setReadChannel(QProcess.StandardOutput)

        while self.proc and self.proc.canReadLine():
            ba = self.proc.readLine()
            if ba.isNull(): return
            str = QString()
            s = QString(str.fromUtf8(ba.data()))[:-1]
            self.logText.append(s)


    def __readFromStderr(self):
        """
        Private slot to handle the readyReadStandardError signal of the process.
        """
        if self.proc is None:
            return
        self.proc.setReadChannel(QProcess.StandardError)

        while self.proc and self.proc.canReadLine():
            ba = self.proc.readLine()
            if ba.isNull(): return
            str = QString()
            s = QString(str.fromUtf8(ba.data()))[:-1]
            self.logText.append(s.prepend('<font color="red">').append('</font>'))
            self.procErrorFlag = True


    def __finished(self):
        if self.objBr:
            CFDSTUDYGUI_DataModel.UpdateSubTree(self.objBr)
        QApplication.restoreOverrideCursor()
        self.pushButton.setEnabled(True)


    def event(self, e):
        if e.type() == 9999:
            return QDialog.event(self, QCloseEvent())

        if e.type() == 9998:
            return QDialog.event(self, QCloseEvent())
        if e.type() == QEvent.Close:
            e.ignore()
            return True

        return QDialog.event(self, e)