navya sri
navya sri

Reputation: 428

How can i run two programs parallelly using Thread with pyqt4

Here in my sample program i want to display my gif upto my process is completed.After my process is completed automatically my gif will close.for that i used here threading function but i am not able to show gif.But i don't have any idea where i did mistake in this program,So can any one please check this program and please guide me.Thank you in advance. Given below is my code:

import sys
from PyQt4 import QtGui
import os

class DialogThread(QtCore.QThread):

    def __init__(self, interval=1):
        self.interval = interval

        thread = threading.Thread(target=self.run, args=())
        thread.daemon = True                            # Daemonize thread
        thread.start()                                  # Start the execution
    def run(self):
        global savingDataFlag,dialog_gif
        """ Method that runs forever """

        while True:
            if savingDataFlag == True:
                dialog_gif.run()
                print 'in saving data true loop'
            else:
                dialog_gif.close()
                print 'in saving data false loop'
                time.sleep(3)

class Dialog(QtGui.QDialog):
    def __init__(self, parent = None):
        super(Dialog, self).__init__(parent)

        self.setStyleSheet("QDialog {background-color:black; color:white }")
        self.label1 = QtGui.QLabel(
            text="Please Wait while It Is Processing The Data...",
            font=QtGui.QFont("Times", 20,weight=QtGui.QFont.Bold)
        )
        self.label21 = QtGui.QLabel()

        vbox1 = QtGui.QVBoxLayout(self)
        vbox1.addWidget(self.label1)
        vbox1.addWidget(self.label21)
        self.resize(640, 480)

    @QtCore.pyqtSlot()
    def show_gif(self):
        movie = QtGui.QMovie(
            "./img/loading1.gif",
            parent=self
        )
        self.label21.setMovie(movie)
        movie.start()
        self.exec_()class Example(QtGui.QWidget):

    def __init__(self):
        super(Example, self).__init__()

        self.initUI()

    def initUI(self):

        okButton = QtGui.QPushButton("Save")
        cancelButton = QtGui.QPushButton("Cancel")
        okButton.clicked.connect(self.save)

        hbox = QtGui.QHBoxLayout()
        hbox.addStretch(1)
        hbox.addWidget(okButton)
        hbox.addWidget(cancelButton)

        vbox = QtGui.QVBoxLayout()
        vbox.addStretch(1)
        vbox.addLayout(hbox)

        self.setLayout(vbox)

        self.setGeometry(300, 300, 300, 150)
        self.setWindowTitle('Buttons')
        self.show()
    def save(self):
        self.d1 = QtGui.QWidget()
        self.form1 = QtGui.QFormLayout(self.d1)
        self.name_file = QtGui.QLabel(("File Name:"))
        self.line_edit1 = QtGui.QLineEdit()
        self.saveBtn1 = QtGui.QPushButton(("Save"))
        self.saveBtn1.clicked.connect(self.saveModelWidget)
        self.canclebtn = QtGui.QPushButton(("Cancel"))
        self.form1.addRow(self.name_file, self.line_edit1)
        self.form1.addRow( self.canclebtn,self.saveBtn1)
        self.d1.setWindowTitle("Enter Grids")
        self.d1.setGeometry(450,300,500,100)
        self.d1.show()
    def saveModelWidget(self):
        self.savefile()
    def savefile(self):
        self.d1.close()
        self.save_text = self.line_edit1.text()
        self.currFilePath = os.getcwd()
        if self.save_text.endsWith(".csv"):
            file_Name= self.save_text
            with open(file_Name, 'w+')as f:
                    dir_path1 =os.getcwd()
                    save_filename = os.path.join(dir_path1,file_Name)
        print "prrocess start"
        # here some execution
        # when i click the save button i want to display the gif file till to complete the process in save file
        print "process ends"

def main():

    app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

Upvotes: 2

Views: 105

Answers (1)

eyllanesc
eyllanesc

Reputation: 244291

You are using QThread with the threading module, and the QThread does not use it since it never starts it, instead you are using threading to execute the run () method. On the other hand overwriting the run method of QThread is a method but many limits many things, instead I will create a worker that will live in another thread. Another error is that movie is a local variable that will be deleted so it will not show, the solution is to pass it a parent. Considering the above the solution is:

import os
import sys
import threading
from PyQt4 import QtCore, QtGui

class SaveWorker(QtCore.QObject):
    started = QtCore.pyqtSignal()
    finished = QtCore.pyqtSignal()

    @QtCore.pyqtSlot(str)
    def save_file(self, filename):
        self.started.emit()
        for i in range(100000):
            print(i)
        with open(filename, 'w+')as f:
            print(filename)
            # some execution
        self.finished.emit()

class GifDialog(QtGui.QDialog):
    def __init__(self, parent = None):
        super(GifDialog, self).__init__(parent)

        self.setStyleSheet("QDialog {background-color:black; color:white }")
        self.label1 = QtGui.QLabel(
            text="Please Wait while It Is Processing The Data...",
            font=QtGui.QFont("Times", 20,weight=QtGui.QFont.Bold)
        )
        self.label2 = QtGui.QLabel()

        vbox = QtGui.QVBoxLayout(self)
        vbox.addWidget(self.label1)
        vbox.addWidget(self.label2)

    @QtCore.pyqtSlot()
    def show_gif(self):
        movie = QtGui.QMovie(
            "./img/loading1.gif", 
            parent=self
        )
        self.label2.setMovie(movie)
        movie.start()
        self.show()

class FormDialog(QtGui.QDialog):
    def __init__(self, parent=None):
        super(FormDialog, self).__init__(parent)
        self.setWindowTitle("Enter Grids")
        self.line_edit = QtGui.QLineEdit()
        self.savebtn = QtGui.QPushButton(
            text="Save",
            clicked=self.save
        )
        self.cancelbtn = QtGui.QPushButton("Cancel")
        #self.savebtn.clicked.connect(self.saveModelWidget)

        flay = QtGui.QFormLayout(self)
        flay.addRow("File Name:", self.line_edit)
        flay.addRow(self.cancelbtn, self.savebtn)
        self.worker = SaveWorker()
        self.gif_dialog = GifDialog(self)
        self.worker.started.connect(self.gif_dialog.show_gif)
        self.worker.finished.connect(self.close)

    @QtCore.pyqtSlot()
    def save(self):
        filename = str(self.line_edit.text())
        if filename.endswith(".csv"):
            save_filename = os.path.join(os.getcwd(), filename)
            thread = threading.Thread(target=self.worker.save_file, args=(save_filename,))
            thread.daemon = True
            thread.start()

class Example(QtGui.QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.initUI()

    def initUI(self):
        okButton = QtGui.QPushButton(
            text="Save",
            clicked=self.on_clicked
        )
        cancelButton = QtGui.QPushButton("Cancel")
        # okButton.clicked.connect(self.save)
        hbox = QtGui.QHBoxLayout()
        hbox.addStretch(1)
        hbox.addWidget(okButton)
        hbox.addWidget(cancelButton)
        vbox = QtGui.QVBoxLayout(self)
        vbox.addStretch(1)
        vbox.addLayout(hbox)

    @QtCore.pyqtSlot()
    def on_clicked(self):
        dialog = FormDialog()
        dialog.exec_()

def main():
    app = QtGui.QApplication(sys.argv)
    dialog = Example()
    dialog.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

Upvotes: 2

Related Questions