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. Show a Loading Home Dialog before starting MainWindow
Forum Updated to NodeBB v4.3 + New Features

Show a Loading Home Dialog before starting MainWindow

Scheduled Pinned Locked Moved Solved Qt for Python
30 Posts 4 Posters 4.8k Views 1 Watching
  • 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.
  • JonBJ JonB

    @hachbani
    Please understand, we have to get pasting/correct code right! When you've tried to help in this forum for as much as I have you never know what posters have actually got if it's not accurate, and I have wasted too much time over the years answering questions about user code which is not actually the code! :)

    I'll think about your connect() now....

    H Offline
    H Offline
    hachbani
    wrote on last edited by
    #21

    Sorry again, I acknowledge that I've been wasting your time for a stupid mistake I've made pasting the code due to a lack of attention.

    JonBJ 1 Reply Last reply
    0
    • H hachbani

      Sorry again, I acknowledge that I've been wasting your time for a stupid mistake I've made pasting the code due to a lack of attention.

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #22

      @hachbani
      That's OK. At least you were polite enough to apologize, which is more than some :)

      You may know PyQt5 more than me. But two things come to mind about your signal declaration

      self.change_val = QtCore.Signal(int)
      
      • PyQt5 signals should be class members, not instance members?
      • You should be using pyqtSignal(int), not QtCore.Signal(int)?
      • Similarly, @pyqtSlot decorator instead of @QtCore.Slot(int)? Don't know if that matters.
      class MainWindow(QtWidgets.QMainWindow,  Ui_MainWindow):
          change_val = pyqtSignal(int)
      

      Do either of those improve? Reference https://doc.bccnsoft.com/docs/PyQt5/signals_slots.html

      1 Reply Last reply
      0
      • H Offline
        H Offline
        hachbani
        wrote on last edited by
        #23

        @hachbani said in Show a Loading Home Dialog before starting MainWindow:

        I'm using Pyside2, pyothn 3.8

        I'm using Pyside2, I'll think more about your first point
        PyQt5 signals should be class members, not instance members?

        JonBJ 1 Reply Last reply
        0
        • H hachbani

          @hachbani said in Show a Loading Home Dialog before starting MainWindow:

          I'm using Pyside2, pyothn 3.8

          I'm using Pyside2, I'll think more about your first point
          PyQt5 signals should be class members, not instance members?

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #24

          @hachbani said in Show a Loading Home Dialog before starting MainWindow:

          I'm using Pyside2,

          Damn, so you are, that changes everything! I got distracted because someone called, damn....

          PyQt5 signals should be class members, not instance members?

          Yes, and I think this applies to PySide2 too, and is the cause of your error message. See 'PySide.QtCore.Signal' object has no attribute 'connect'?

          And/or further, does your MainWindow.__init__() call super().__init__()? Omitting that can apparently lead to that error message too.

          Finally, since your own signal does not seem to have multiple overloads, you could try plain

          change_val.connect(self.set_progress_val)
          

          without that [int].

          See also https://wiki.qt.io/Qt_for_Python_Signals_and_Slots

          1 Reply Last reply
          0
          • H Offline
            H Offline
            hachbani
            wrote on last edited by
            #25

            I've declared change_val as a class member, I get an error name 'change_val' is not defined

            I've updated the code in my last comment. I do indeed call super in MainWindow init()

            JonBJ 1 Reply Last reply
            0
            • H hachbani

              I've declared change_val as a class member, I get an error name 'change_val' is not defined

              I've updated the code in my last comment. I do indeed call super in MainWindow init()

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #26

              @hachbani said in Show a Loading Home Dialog before starting MainWindow:

              've declared change_val as a class member, I get an error name 'change_val' is not defined

              Refer the https://wiki.qt.io/Qt_for_Python_Signals_and_Slots I quoted earlier for examples. It may be that to reference the class variable you have to go self.change_val or MainWindow.change_val?

              1 Reply Last reply
              0
              • H Offline
                H Offline
                hachbani
                wrote on last edited by
                #27

                Thanjs @JonB for you help ! Indeed the self.change_val worked. I get my ProgressDialog, I added some prints in set_progress_val to debug if it's been called correctly, and it is. The problem is the progressDialog freezes, no progress is shown.

                Here's the actual code:

                
                class MainWindow(QtWidgets.QMainWindow,  Ui_MainWindow):
                    change_val = QtCore.Signal(int)
                
                    def __init__(self, file_name,parent=None):
                        """
                        super(MainWindow, self).__init__(parent)
                        ..
                        __init__ code lines
                        """
                
                        self.change_val[int].connect(self.set_progress_val)
                        self.progress = QtWidgets.QProgressDialog('loading...', 'cancel', 0, 100, self)
                        self.progress.setValue(0)
                        self.progress.show()
                        self.LoadData(d.path)
                    
                    @QtCore.Slot(int)
                    def set_progress_val(self, val):
                        print('progress setVal called, new val: ', self.progress.value())
                        self.progress.setValue(val)
                
                    def LoadData(self, file_path):
                        
                        """
                        Parsing lines of code
                        ..
                        self.change_val.emit(30)
                        ..
                        ..
                        self.change_val.emit(60)
                        ..
                        ..
                        """
                        self.change_val.emit(100)
                        #Parsing finished -> show the mainWindow
                        self.show()
                
                class HomeDialog(QtWidgets.QDialog, home_dialog.Ui_Dialog):
                    def __init__(self, parent=None):
                        super(HomeDialog, self).__init__(parent)
                        self.setupUi(self)
                        self.openB6.clicked.connect(self.get_file_name)
                
                    def get_file_name(self):
                        file_name = QtWidgets.QFileDialog.getOpenFileName(self, 'Open config file',
                                                                            dir=path.join("/"),
                                                                            filter="B6 (*.b6)")
                        if not file_name[0]:
                            return None
                        else:
                            self.path = file_name
                            self.accept()
                
                if __name__ == '__main__':
                    app = QtWidgets.QApplication(sys.argv)
                    app.setStyle(ProxyStyle())
                    d = HomeDialog()
                    if d.exec_():
                        mainWin = MainWindow(file_name=d.path)
                        mainWin.show()
                        sys.exit(app.exec_())
                

                Here's a screenshot of the displayed window when progressDialog is displayed:

                df738644-f964-4ead-bd2a-6c45d765e981-image.png

                JonBJ 1 Reply Last reply
                0
                • H hachbani

                  Thanjs @JonB for you help ! Indeed the self.change_val worked. I get my ProgressDialog, I added some prints in set_progress_val to debug if it's been called correctly, and it is. The problem is the progressDialog freezes, no progress is shown.

                  Here's the actual code:

                  
                  class MainWindow(QtWidgets.QMainWindow,  Ui_MainWindow):
                      change_val = QtCore.Signal(int)
                  
                      def __init__(self, file_name,parent=None):
                          """
                          super(MainWindow, self).__init__(parent)
                          ..
                          __init__ code lines
                          """
                  
                          self.change_val[int].connect(self.set_progress_val)
                          self.progress = QtWidgets.QProgressDialog('loading...', 'cancel', 0, 100, self)
                          self.progress.setValue(0)
                          self.progress.show()
                          self.LoadData(d.path)
                      
                      @QtCore.Slot(int)
                      def set_progress_val(self, val):
                          print('progress setVal called, new val: ', self.progress.value())
                          self.progress.setValue(val)
                  
                      def LoadData(self, file_path):
                          
                          """
                          Parsing lines of code
                          ..
                          self.change_val.emit(30)
                          ..
                          ..
                          self.change_val.emit(60)
                          ..
                          ..
                          """
                          self.change_val.emit(100)
                          #Parsing finished -> show the mainWindow
                          self.show()
                  
                  class HomeDialog(QtWidgets.QDialog, home_dialog.Ui_Dialog):
                      def __init__(self, parent=None):
                          super(HomeDialog, self).__init__(parent)
                          self.setupUi(self)
                          self.openB6.clicked.connect(self.get_file_name)
                  
                      def get_file_name(self):
                          file_name = QtWidgets.QFileDialog.getOpenFileName(self, 'Open config file',
                                                                              dir=path.join("/"),
                                                                              filter="B6 (*.b6)")
                          if not file_name[0]:
                              return None
                          else:
                              self.path = file_name
                              self.accept()
                  
                  if __name__ == '__main__':
                      app = QtWidgets.QApplication(sys.argv)
                      app.setStyle(ProxyStyle())
                      d = HomeDialog()
                      if d.exec_():
                          mainWin = MainWindow(file_name=d.path)
                          mainWin.show()
                          sys.exit(app.exec_())
                  

                  Here's a screenshot of the displayed window when progressDialog is displayed:

                  df738644-f964-4ead-bd2a-6c45d765e981-image.png

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by
                  #28

                  @hachbani
                  Because LoadData() is in your GUI thread, Qt does not get to redraw/refresh the UI while it is running. I assume your bar shows once as "full" right at the end? I haven't used QProgressBar, but I imagine you should play with one of the following:

                  • Move LoadFile() to its own thread. That's the nicest, but can be the most code.

                  • Try self.progress.repaint() in your slot.

                  • Try QCoreApplication.processEvents() in your slot.

                  Is set_progress_val() called against each emit()? I think it is, because you are using DirectConnection; if not you can always call set_progress_val() directly instead of going via a signal.

                  1 Reply Last reply
                  3
                  • H Offline
                    H Offline
                    hachbani
                    wrote on last edited by
                    #29

                    Hey, thanks so much man !!! I added QtCore.QCoreApplication.processEvents() to my slot, and it works !!

                    Maybe I'm going to take a look really later on the first point, about moving LoadData() to another thread, it seems interesting (I just never worked with QThread)

                    going to update the post with the full solution later, in case It'd save someone's day.

                    Have a nice week

                    JonBJ 1 Reply Last reply
                    1
                    • H hachbani

                      Hey, thanks so much man !!! I added QtCore.QCoreApplication.processEvents() to my slot, and it works !!

                      Maybe I'm going to take a look really later on the first point, about moving LoadData() to another thread, it seems interesting (I just never worked with QThread)

                      going to update the post with the full solution later, in case It'd save someone's day.

                      Have a nice week

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by
                      #30

                      @hachbani
                      Threads are tempting, especially for beginners, but nasty to get right, and I think more of an issue in Python than C++.

                      processEvents() is a bit "naughty", but awfully simple if it works. You probably have more important things to move onto than spending ages on a loading progress screen :)

                      The only thing is: if your LoadData() takes a bit of time, try clicking on something on the main window which has a slot action while it is still loading the data. The problem is that slot will execute, and if it expects your data load to be complete it won't be.

                      Have a look at the example at https://doc.qt.io/qt-5/qprogressdialog.html#details where

                      Compared to a modeless QProgressDialog, a modal QProgressDialog is simpler to use for the programmer. Do the operation in a loop, call setValue() at intervals

                      Is that code implying you can call QProgressDialog.setValue() as you go along without you having to worry about the event loop for updates? If that pattern works for you I'd be tempted to adopt it?

                      1 Reply Last reply
                      2

                      • Login

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