Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Must construct a QApplication before a QWidget
QtWS25 Last Chance

Must construct a QApplication before a QWidget

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 4 Posters 8.7k 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.
  • T Offline
    T Offline
    Thiyo
    wrote on last edited by Chris Kawa
    #1

    hello,
    I have created a GUI Windows app. It starts with a splash screen and then transitions to the main window (home screen), allowing users to navigate to other pages by clicking on buttons. The use of the timer to automatically close the splash screen after a certain time. when I ran my below code I got an error message QWidget: Must construct a QApplication before a QWidget .. please help me to solve this.
    code 👇

    import sys
    from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton
    from PyQt5.QtCore import QTimer, Qt
    from PyQt5.QtGui import QPixmap
    from PyQt5 import uic, QtWidgets, QtGui, QtCore
    from ui_splash_screen import Ui_SplashScreen
    
    # Your existing SplashScreen class
    class SplashScreen(QMainWindow):
        # ... (your existing SplashScreen code here) ...
        def __init__(self):
            QtWidgets.QMainWindow.__init__(self)
            self.ui = Ui_SplashScreen()
            self.ui.setupUi(self)
    
            # remove titile bar
            self.setWindowFlag(QtCore.Qt.FramelessWindowHint)
            self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
    
            # set app logo
            pixmap = QtGui.QPixmap("logo.png")
            self.ui.log_img.setPixmap(pixmap)
            self.ui.log_img.setScaledContents(True)
            self.ui.log_img.setSizePolicy(
                QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Ignored)
    
            # hide background
            self.ui.background.setMaximumHeight(0)
    
            # SET INITIOLS STATUS
            self.ui.status.setText("Loading..")
    
            # Initialize animation
            self.logo_animation()
            self.description_animation()
            self.start_animation()
    
            # qtimer
            self.timer = QtCore.QTimer()
            self.timer.timeout.connect(self.progress)
            # time in milisecond
            self.timer.start(35)
    
            # change status
            QtCore.QTimer.singleShot(
                2500, lambda: self.ui.status.setText("Loading Data...."))
            QtCore.QTimer.singleShot(
                4500, lambda: self.ui.status.setText("Loading App...."))
            QtCore.QTimer.singleShot(
                6500, lambda: self.ui.status.setText("Starting App...."))
    
        # animate app logo
    
        def logo_animation(self):
            opacity_effect = QtWidgets.QGraphicsOpacityEffect(self.ui.log_img)
            self.ui.log_img.setGraphicsEffect(opacity_effect)
    
            self.logo_opacity_animation = QtCore.QPropertyAnimation(
                opacity_effect, b'opacity', duration=1500, startValue=0, endValue=1
            )
            self.logo_opacity_animation.setEasingCurve(
                QtCore.QEasingCurve.InOutCubic)
            self.logo_opacity_animation.start()
    
        # animate app description
        # ////////////////////////////////
        def description_animation(self):
            opacity_effect = QtWidgets.QGraphicsOpacityEffect(self.ui.background)
            self.ui.background.setGraphicsEffect(opacity_effect)
    
            geometry_animation = QtCore.QPropertyAnimation(
                self.ui.background,
                b'maximumHeight',
                duration=1000,
                startValue=0,
                endValue=228,
            )
            geometry_animation.setEasingCurve(QtCore.QEasingCurve.InOutCubic)
    
            opacity_animation = QtCore.QPropertyAnimation(
                opacity_effect, b'opacity', duration=500, startValue=0, endValue=1
            )
    
            self.description_animation = QtCore.QParallelAnimationGroup(
                self.ui.background)
            self.description_animation.addAnimation(geometry_animation)
            self.description_animation.addAnimation(opacity_animation)
    
        # start animation
        def start_animation(self):
            self.anim_group = QtCore.QSequentialAnimationGroup(self)
            self.anim_group.addAnimation(self.logo_opacity_animation)
            self.anim_group.addAnimation(self.description_animation)
            self.anim_group.start()
    
        # progress function
    
        def progress(self):
            global COUNTER
    
            # set value to progressbar
            self.ui.progressBar.setValue(COUNTER)
            self.ui.percentage.setText(f"{int(COUNTER)}%")
    
            # CLOSE SPLASH SCREEN AND OPEN APP
            if COUNTER > 100:
                # STOP TIMER
                self.timer.stop()
    
                # SHOW MAIN WINDOW
                self.main = MainWindow()
                self.main.show()
    
                # CLOSE SPLASH SCREEN
                self.close()
    
    
    # Main application window
    class MainWindow(QMainWindow):
        def __init__(self):
            super().__init__()
    
            # Load the UI from main_window.ui (your home screen)
            self.load_ui("main_window.ui")
    
            # Connect button clicks to relevant actions
            self.take_sample_btn.clicked.connect(self.show_take_sample_screen)
            self.train_model_btn.clicked.connect(self.show_train_model_screen)
            self.calibrate_btn.clicked.connect(self.show_calibrate_screen)
            self.get_prediction_btn.clicked.connect(self.show_get_prediction_screen)
            self.pick_a_model_btn.clicked.connect(self.show_pick_a_model_screen)
            self.quit_btn.clicked.connect(self.show_close_screen)
    
        def load_ui(self, ui_file):
            # Function to load UI files
            uic.loadUi(ui_file, self)
    
        def show_take_sample_screen(self):
            # Handle button click to navigate to TakeSampleScreen
            self.load_ui("take_sample_screen.ui")
            self.setup_take_sample_screen_ui()
            # Add more setup code as needed...
    
        def show_train_model_screen(self):
            # Handle button click to navigate to TrainModelScreen
            self.load_ui("model_training_screen.ui")
            self.setup_train_model_screen_ui()
            # Add more setup code as needed...
    
        def show_calibrate_screen(self):
            self.load_ui("calibrate_screen.ui")
            self.setup_calibrate_screen_ui()
        # Add similar methods for other screens...
    
        def show_get_prediction_screen(self):
            self.load_ui("prediction_screen.ui")
            self.setup_get_prediction_ui()
    
        def show_pick_a_model_screen(self):
            self.load_ui("pick_model.ui")
            self.setup_pick_model_ui()
    
        def show_close_screen(self):
            QtCore.QCoreApplication.quit()
    
        def setup_take_sample_screen_ui(self):
            # Setup UI elements for TakeSampleScreen
            self.backButton.clicked.connect(self.show_main_window)
            # Add more setup code as needed...
    
        def setup_train_model_screen_ui(self):
            # Setup UI elements for TrainModelScreen
            self.backButton.clicked.connect(self.show_main_window)
            # Add more setup code as needed...
        
        def setup_calibrate_screen_ui(self):
            self.backButton.clicked.connect(self.show_main_window)
    
        def setup_get_prediction_ui(self):
            self.backButton.clicked.connect(self.show_main_window)
    
        def setup_pick_model_ui(self):
            self.backButton.clicked.connect(self.show_main_window)
    
        # Add similar setup methods for other screens...
    
        def show_main_window(self):
            # Return to the main window (home screen)
            self.load_ui("main_window.ui")
    
    
    def main():
        # Create the QApplication instance
        app = QApplication(sys.argv)
    
        # Create the SplashScreen object
        splash_screen = SplashScreen()
        splash_screen.show()
    
        # Create a timer to close the splash screen after a certain time (e.g., 3 seconds)
        timer = QTimer()
        timer.timeout.connect(splash_screen.close)
        timer.start(3000)  # 3000 milliseconds (3 seconds)
    
        splash_screen.finished.connect(lambda: show_main_window())
    
        sys.exit(app.exec_())
    
    
    def show_main_window():
        global main_window
        main_window = MainWindow()
        main_window.show()
    
    if __name__ == '__main__':
        main()
    
    

    this is the terminal output 👇
    Screenshot 2023-09-11 015357.png

    JonBJ 1 Reply Last reply
    0
    • T Thiyo

      hello,
      I have created a GUI Windows app. It starts with a splash screen and then transitions to the main window (home screen), allowing users to navigate to other pages by clicking on buttons. The use of the timer to automatically close the splash screen after a certain time. when I ran my below code I got an error message QWidget: Must construct a QApplication before a QWidget .. please help me to solve this.
      code 👇

      import sys
      from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton
      from PyQt5.QtCore import QTimer, Qt
      from PyQt5.QtGui import QPixmap
      from PyQt5 import uic, QtWidgets, QtGui, QtCore
      from ui_splash_screen import Ui_SplashScreen
      
      # Your existing SplashScreen class
      class SplashScreen(QMainWindow):
          # ... (your existing SplashScreen code here) ...
          def __init__(self):
              QtWidgets.QMainWindow.__init__(self)
              self.ui = Ui_SplashScreen()
              self.ui.setupUi(self)
      
              # remove titile bar
              self.setWindowFlag(QtCore.Qt.FramelessWindowHint)
              self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
      
              # set app logo
              pixmap = QtGui.QPixmap("logo.png")
              self.ui.log_img.setPixmap(pixmap)
              self.ui.log_img.setScaledContents(True)
              self.ui.log_img.setSizePolicy(
                  QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Ignored)
      
              # hide background
              self.ui.background.setMaximumHeight(0)
      
              # SET INITIOLS STATUS
              self.ui.status.setText("Loading..")
      
              # Initialize animation
              self.logo_animation()
              self.description_animation()
              self.start_animation()
      
              # qtimer
              self.timer = QtCore.QTimer()
              self.timer.timeout.connect(self.progress)
              # time in milisecond
              self.timer.start(35)
      
              # change status
              QtCore.QTimer.singleShot(
                  2500, lambda: self.ui.status.setText("Loading Data...."))
              QtCore.QTimer.singleShot(
                  4500, lambda: self.ui.status.setText("Loading App...."))
              QtCore.QTimer.singleShot(
                  6500, lambda: self.ui.status.setText("Starting App...."))
      
          # animate app logo
      
          def logo_animation(self):
              opacity_effect = QtWidgets.QGraphicsOpacityEffect(self.ui.log_img)
              self.ui.log_img.setGraphicsEffect(opacity_effect)
      
              self.logo_opacity_animation = QtCore.QPropertyAnimation(
                  opacity_effect, b'opacity', duration=1500, startValue=0, endValue=1
              )
              self.logo_opacity_animation.setEasingCurve(
                  QtCore.QEasingCurve.InOutCubic)
              self.logo_opacity_animation.start()
      
          # animate app description
          # ////////////////////////////////
          def description_animation(self):
              opacity_effect = QtWidgets.QGraphicsOpacityEffect(self.ui.background)
              self.ui.background.setGraphicsEffect(opacity_effect)
      
              geometry_animation = QtCore.QPropertyAnimation(
                  self.ui.background,
                  b'maximumHeight',
                  duration=1000,
                  startValue=0,
                  endValue=228,
              )
              geometry_animation.setEasingCurve(QtCore.QEasingCurve.InOutCubic)
      
              opacity_animation = QtCore.QPropertyAnimation(
                  opacity_effect, b'opacity', duration=500, startValue=0, endValue=1
              )
      
              self.description_animation = QtCore.QParallelAnimationGroup(
                  self.ui.background)
              self.description_animation.addAnimation(geometry_animation)
              self.description_animation.addAnimation(opacity_animation)
      
          # start animation
          def start_animation(self):
              self.anim_group = QtCore.QSequentialAnimationGroup(self)
              self.anim_group.addAnimation(self.logo_opacity_animation)
              self.anim_group.addAnimation(self.description_animation)
              self.anim_group.start()
      
          # progress function
      
          def progress(self):
              global COUNTER
      
              # set value to progressbar
              self.ui.progressBar.setValue(COUNTER)
              self.ui.percentage.setText(f"{int(COUNTER)}%")
      
              # CLOSE SPLASH SCREEN AND OPEN APP
              if COUNTER > 100:
                  # STOP TIMER
                  self.timer.stop()
      
                  # SHOW MAIN WINDOW
                  self.main = MainWindow()
                  self.main.show()
      
                  # CLOSE SPLASH SCREEN
                  self.close()
      
      
      # Main application window
      class MainWindow(QMainWindow):
          def __init__(self):
              super().__init__()
      
              # Load the UI from main_window.ui (your home screen)
              self.load_ui("main_window.ui")
      
              # Connect button clicks to relevant actions
              self.take_sample_btn.clicked.connect(self.show_take_sample_screen)
              self.train_model_btn.clicked.connect(self.show_train_model_screen)
              self.calibrate_btn.clicked.connect(self.show_calibrate_screen)
              self.get_prediction_btn.clicked.connect(self.show_get_prediction_screen)
              self.pick_a_model_btn.clicked.connect(self.show_pick_a_model_screen)
              self.quit_btn.clicked.connect(self.show_close_screen)
      
          def load_ui(self, ui_file):
              # Function to load UI files
              uic.loadUi(ui_file, self)
      
          def show_take_sample_screen(self):
              # Handle button click to navigate to TakeSampleScreen
              self.load_ui("take_sample_screen.ui")
              self.setup_take_sample_screen_ui()
              # Add more setup code as needed...
      
          def show_train_model_screen(self):
              # Handle button click to navigate to TrainModelScreen
              self.load_ui("model_training_screen.ui")
              self.setup_train_model_screen_ui()
              # Add more setup code as needed...
      
          def show_calibrate_screen(self):
              self.load_ui("calibrate_screen.ui")
              self.setup_calibrate_screen_ui()
          # Add similar methods for other screens...
      
          def show_get_prediction_screen(self):
              self.load_ui("prediction_screen.ui")
              self.setup_get_prediction_ui()
      
          def show_pick_a_model_screen(self):
              self.load_ui("pick_model.ui")
              self.setup_pick_model_ui()
      
          def show_close_screen(self):
              QtCore.QCoreApplication.quit()
      
          def setup_take_sample_screen_ui(self):
              # Setup UI elements for TakeSampleScreen
              self.backButton.clicked.connect(self.show_main_window)
              # Add more setup code as needed...
      
          def setup_train_model_screen_ui(self):
              # Setup UI elements for TrainModelScreen
              self.backButton.clicked.connect(self.show_main_window)
              # Add more setup code as needed...
          
          def setup_calibrate_screen_ui(self):
              self.backButton.clicked.connect(self.show_main_window)
      
          def setup_get_prediction_ui(self):
              self.backButton.clicked.connect(self.show_main_window)
      
          def setup_pick_model_ui(self):
              self.backButton.clicked.connect(self.show_main_window)
      
          # Add similar setup methods for other screens...
      
          def show_main_window(self):
              # Return to the main window (home screen)
              self.load_ui("main_window.ui")
      
      
      def main():
          # Create the QApplication instance
          app = QApplication(sys.argv)
      
          # Create the SplashScreen object
          splash_screen = SplashScreen()
          splash_screen.show()
      
          # Create a timer to close the splash screen after a certain time (e.g., 3 seconds)
          timer = QTimer()
          timer.timeout.connect(splash_screen.close)
          timer.start(3000)  # 3000 milliseconds (3 seconds)
      
          splash_screen.finished.connect(lambda: show_main_window())
      
          sys.exit(app.exec_())
      
      
      def show_main_window():
          global main_window
          main_window = MainWindow()
          main_window.show()
      
      if __name__ == '__main__':
          main()
      
      

      this is the terminal output 👇
      Screenshot 2023-09-11 015357.png

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

      @Thiyo
      Hello and welcome.

      It would be helpful if you used the Code tags (</> icon) around any code blocks, especially if you use python where lead spacing is vital. If you did this it might be easier to spot where a QWidget is created before a QApplication, e.g. perhaps in a global variable you have?

      1 Reply Last reply
      1
      • Paul ColbyP Offline
        Paul ColbyP Offline
        Paul Colby
        wrote on last edited by
        #3

        Hi @Thiyo,

        QMainWindow inherits QWidget, so this line is creating a QWidget globally:

        global main_window

        Which, of course, is happening before your main creates the QApplication, thus the error message you see.

        As per the docs, you need to create your main_window after you create the QMainApplication - most likely by making main_window non-global, but I'll leave the exact details to you and others that know Python better than I do :)

        Cheers.

        JonBJ 1 Reply Last reply
        0
        • Paul ColbyP Paul Colby

          Hi @Thiyo,

          QMainWindow inherits QWidget, so this line is creating a QWidget globally:

          global main_window

          Which, of course, is happening before your main creates the QApplication, thus the error message you see.

          As per the docs, you need to create your main_window after you create the QMainApplication - most likely by making main_window non-global, but I'll leave the exact details to you and others that know Python better than I do :)

          Cheers.

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

          @Paul-Colby said in Must construct a QApplication before a QWidget:

          global main_window

          I'm sure you're right. But I thought global in Python gave the variable global scope but did not actually create it until the statement is first hit, which is inside def show_main_window(): and therefore not until that function is first called, which is not until after main() is called and app = QApplication(sys.argv) has been executed? Python global is confusing....!

          P.S.
          My advice to @Thiyo is don't use global at all in Python/Qt, C++ manages without needing to do so here!

          jeremy_kJ 1 Reply Last reply
          0
          • JonBJ JonB

            @Paul-Colby said in Must construct a QApplication before a QWidget:

            global main_window

            I'm sure you're right. But I thought global in Python gave the variable global scope but did not actually create it until the statement is first hit, which is inside def show_main_window(): and therefore not until that function is first called, which is not until after main() is called and app = QApplication(sys.argv) has been executed? Python global is confusing....!

            P.S.
            My advice to @Thiyo is don't use global at all in Python/Qt, C++ manages without needing to do so here!

            jeremy_kJ Offline
            jeremy_kJ Offline
            jeremy_k
            wrote on last edited by
            #5

            @JonB said in Must construct a QApplication before a QWidget:

            @Paul-Colby said in Must construct a QApplication before a QWidget:

            global main_window

            I'm sure you're right. But I thought global in Python gave the variable global scope but did not actually create it

            That is correct. global x doesn't create an object. It tells the interpreter that future references within the scope in question refer to a global rather than local variable. There's no type information, so the interpreter can't create an object at that point.

            until the statement is first hit, which is inside def show_main_window():

            We can't tell without the indentation. The code could be:

            def show_main_window():
               global main_window
            
            main_window = MainWindow() # Interpreted as part of the module, not a function.
            

            Asking a question about code? http://eel.is/iso-c++/testcase/

            JonBJ 1 Reply Last reply
            2
            • jeremy_kJ jeremy_k

              @JonB said in Must construct a QApplication before a QWidget:

              @Paul-Colby said in Must construct a QApplication before a QWidget:

              global main_window

              I'm sure you're right. But I thought global in Python gave the variable global scope but did not actually create it

              That is correct. global x doesn't create an object. It tells the interpreter that future references within the scope in question refer to a global rather than local variable. There's no type information, so the interpreter can't create an object at that point.

              until the statement is first hit, which is inside def show_main_window():

              We can't tell without the indentation. The code could be:

              def show_main_window():
                 global main_window
              
              main_window = MainWindow() # Interpreted as part of the module, not a function.
              
              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #6

              @jeremy_k said in Must construct a QApplication before a QWidget:

              We can't tell without the indentation. The code could be:

              Ah, yes, exactly! Which is why I asked the OP to use code tags especially for Python for just this reason :)

              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