2

From this PyQt - Modify GUI from another thread I learnt that "In Qt you should never attempt to directly update the GUI from outside of the GUI thread." This is why in my PyQt5 program I have a thread (Monitor), "run" method of which emits a signal to a slot (MainWindow.save_file), which in turn shows QtWidgets.QFileDialog.getSaveFileName and accepts user's input. So my question is: how can I make this MainWindow.save_file to return the user's input to a Monitor thread.

    class Communicate(QtCore.QObject):
        show_save_file = QtCore.pyqtSignal()

    class Monitor(QtCore.QThread):
        def run(self):
            self.c = Communicate()
            self.c.show_save_file.connect(MainWindow.save_file)
            self.c.show_save_file.emit()

    class MainWindow(QtWidgets.QMainWindow):

        def __init__(self):
            super().__init__()
            self.setupUi() 

        # Some other PyQt stuff here....

        def save_file(self):
            # I need this slot to return out_file_name to another thread,   Monitor
            sender = self.sender()
            out_file_name = QtWidgets.QFileDialog.getSaveFileName(self, '', '', 'flv')

Any help is greatly appreciated.

Community
  • 1
  • 1
Yurkol
  • 1,414
  • 1
  • 19
  • 28
  • 1
    In your example, the thread finishes after it emits the signal (i.e. once its `run()` method returns). So what you're asking doesn't seem to make complete sense. Maybe you should post a more [realistic example](http://stackoverflow.com/help/mcve). – ekhumoro Oct 23 '15 at 16:07
  • Dear ekhumoro. No, the thread does not stop after emitting the signal. Maybe you should post a concrete answer. – Yurkol Oct 24 '15 at 02:46
  • 1
    The documentation of [QThread.run](http://doc.qt.io/qt-4.8/qthread.html#run) is very clear (see the last sentence). – ekhumoro Oct 24 '15 at 15:40

1 Answers1

2

I think it's too late for the answer, but something is better than nothing.

I have tested partial code but couldn't test the complete code due to some reasons, but it should work.

Do give it a try:

class Communicate(QtCore.QObject):
    show_save_file = QtCore.pyqtSignal()
    fileName = None

class Monitor(QtCore.QThread):
    def run(self):
        self.c = Communicate()
        self.c.show_save_file.connect(MainWindow.save_file)
        self.c.show_save_file.emit()
        
        while (Communicate.fileName == None):
            # This will make the thread wait until it gets fileName
            # If you want, add time.sleep or something to poll at
            # intervals rather than continuously polling.
            pass
        
        fileName = Communicate.fileName
        Communicate.fileName = None
        # setting this None to make sure next time it doesn't get
        # wrong fileName, if it runs again.

class MainWindow(QtWidgets.QMainWindow):

    def __init__(self):
        super().__init__()
        self.setupUi() 

    
    def save_file(self):
        sender = self.sender()
        out_file_name = QtWidgets.QFileDialog.getSaveFileName(
            self, '', '', 'flv'
        )
        Communicate.fileName = out_file_name