Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. PySide 6: GUI Freezing even when using QThreadPool class

PySide 6: GUI Freezing even when using QThreadPool class

Scheduled Pinned Locked Moved Solved Qt for Python
pyside2pysidepythonqt for python
4 Posts 2 Posters 1.9k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    ccortez
    wrote on last edited by
    #1

    I am currently building a GUI using PySide6. I am running into some issues with the qthreadpool threading.

    I have a method where I perform some heavy computation, that will end up freezing the GUI if left on the main thread. I have used qthreadpool for otber methods in my code, and it has worked just fine. For some reason, there is a specific part of my code right now that isn't working as intended. I launch that method in a threadpool thread, and the GUI still freezes up. To me this means that it's not making it outside the mainthread, or there is some other bigger issue. I can't really narrow it down, since I've been using qthreadpool this whole time and it has worked fine.

    ANy guidance or help with this would be great, I am a bit stuck at this point.

    Here is my code:

    class dataSignal(QObject):
        data_received = Signal(object)
    class DataPlotting(QMainWindow):
        def __init__(self):
            super(DataPlotting, self).__init__()
            # Styling and window layout
            screen = QApplication.primaryScreen().size().width()
            window = self.frameGeometry().width()
            self.move(int(screen / 2) - int(window / 2),0)
            self.setWindowTitle('GUI App')
    
            self.setStyleSheet('''...''')
    
            # Initializing Variables for data log file
            self.threadpool = QThreadPool()
            self.plotting_signal_con = dataSignal()
            self.plotting_signal_con.data_received.connect(self.plotting_ready)
            self.data = {}
    
            # Sample Button to Graph Data, this is the button where I launch heavy computation
            # but the GUI still freezes
            self.graph = QPushButton('Graph Data', self)
            self.graph.setToolTip('Graph Data')
            self.graph.setEnabled(False)
            self.graph.clicked.connect(self.threader) # connects to funciton that launches thread
    
        @Slot()
        def plotting_ready(self, info):
           # Here all i do is  call a function in another file that plots the data based on selected x and y 
           # variables (not included in this code)
            self.console.append(info)
            plotting(list(self.data.values()), self.xvar, self.yvars, self.footers)
    
        def plot_cb(self, info):
            self.plotting_signal_con.data_received.emit(info)
    
       # We launch the thread here 
        def threader(self):
            self.threadpool.start(self.ProcessDataLogs2(self.plot_cb))
    
        def ProcessDataLogs2(self, callback):
             for i, file in enumerate(self.data):
                #This is where the heavy computation happens 
                # All i really do is read in a file from pandas based on different conditions, so I am just going to  
                # include that line 
                df = pd.read_csv(file
                self.data[file]) = df
             
             # Once that is done, we send info in the call back function to signal that this process is done, 
             and it goes to the function plotting_ready
             info = 'Data Processing Finished & Plots Created...'
             callback(info)
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      I think the issue is that you are using a callback to emit the signal.

      If you want to emit a signal from a different thread, you should use QMetaObject::invokeMethod.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      C 1 Reply Last reply
      0
      • SGaistS SGaist

        Hi,

        I think the issue is that you are using a callback to emit the signal.

        If you want to emit a signal from a different thread, you should use QMetaObject::invokeMethod.

        C Offline
        C Offline
        ccortez
        wrote on last edited by
        #3

        @SGaist Hi I appreciate your response.

        I dont think that this is the problem if I am being honest. The reason why I say that is because I am doing the exact same process for another method in my code, and that one works exactly as intended.

        If it helps, here is the code for that chunk:

        class dataSignal(QObject):
            data_received = Signal(object)
        class DataPlotting(QMainWindow):
            def __init__(self):
                super(DataPlotting, self).__init__()
                # Styling and window layout
                screen = QApplication.primaryScreen().size().width()
                window = self.frameGeometry().width()
                self.move(int(screen / 2) - int(window / 2),0)
                self.setWindowTitle('GUI App')
        
                self.setStyleSheet('''...''')
        
                # Initializing Variables for data log file
                self.threadpool = QThreadPool()
                self.signal_con = dataSignal()
                self.signal_con.data_received.connect(self.data_ready)       
                self.data = {}
        
                self.pandas_profile_button = QPushButton('Build Statistical Report')
                self.pandas_profile_button.setToolTip('Creates an HTML file containing a statistical breakdown of selected data')
                self.pandas_profile_button.setEnabled(False)
                self.pandas_profile_button.clicked.connect(self.pandas_report_th)
        
            @Slot()
            def data_ready(self, info):
                self.progress_bar.setValue(100)
                self.console.append(info)
        
            def cb(self, info):
                self.signal_con.data_received.emit(info)
            
            def pandas_report_th(self):
                self.threadpool.start(self.pandas_report)
        
            def pandas_report(self):
                # This one essentially odes the same thing, read a csv and process it for some actions, it goes one thread farther
                  
                df = pd.read_csv(file
                self.data[file]) = df
        
                self.threadpool.start(self.pandas_report5(self.cb))
            def pandas_report5(self, callback):
              
                prof = ProfileReport(self.data[file])
              
                filename = file.replace('.txt', ' Statistical Report.html')
              
                prof.to_file(output_file=filename)
              
                print('Report done')
              
                result = 'Your report has been saved at: ' + filename
              
                callback(result)
        
        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          So the one that creates a file is working but the one that changes a GUI element freezes ? Do I get you correctly ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved