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. Issue opening new window

Issue opening new window

Scheduled Pinned Locked Moved Solved Qt for Python
15 Posts 3 Posters 2.5k 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.
  • O orsini29

    @JonB

    I changed the __init__ to be the following within AddNewMachineScreen.py

        def __init__(self):
            print("here0")
            super().__init__()
            self.setupUi(self)
            self.connect_slots(self
    

    And put a breakpoint on the following line within widget.py

        @QtCore.Slot()
        def add_machine_button_clicked(self):
            self.local = AddNewMachineScreen()   ####BREAKPOINT HERE
            self.local_widget = QWidget()
            self.local.setupUi(self.local_widget)
            self.local_widget.show()
    

    Then when using F11 to Step Into, when it gets to the line with the breakpoint it just goes to the next line self.local_widget = QWidget() and it does not go into a function until the self.local.setupUi(self.local_widget) goes into the ui_addnewmachinescreen.py file.

    This is saying it basically does not run the constructor for the AddNewMachineScreen class...thinking out loud trying to figure out why.

    It could not have anything to do with the following import statement, right? I assumed this is correct syntax as I do not see why it would not be valid...

    from ui_addNewMachineScreen import Ui_Widget as AddNewMachineScreen
    
    JonBJ Offline
    JonBJ Offline
    JonB
    wrote on last edited by JonB
    #6

    @orsini29
    I had not noticed that. I am OK an Python, but not an expert. Yes, it must be the explanation for inexplicable behaviour you report.

    I don't know what you think are trying to achieve, but you are "messing it up" :)

    class AddNewMachineScreen(QWidget, Ui_Widget)

    This defines a class named AddNewMachineScreen(). And calling AddNewMachineScreen() would invoke its __init__() as I was expecting.

    from ui_addNewMachineScreen import Ui_Widget as AddNewMachineScreen

    This "redefines" AddNewMachineScreen. It now "refers to" Ui_Widget, as an "alias". It cannot also refer to the class you defined at the same time. I guess in Python this overrides the class definition. So invoking AddNewMachineScreen() now actually does Ui_Widget(), whatever that does. Hence you never create an AddNewMachineScreen or hit its __init__().

    I do not claim to understand what you are trying to do. I can say that you have absolutely no need to do an import ... as ..., that is just for aliasing. I suggest whatever you are trying to achieve you remove any such construct and start over....

    O 1 Reply Last reply
    0
    • JonBJ JonB

      @orsini29
      I had not noticed that. I am OK an Python, but not an expert. Yes, it must be the explanation for inexplicable behaviour you report.

      I don't know what you think are trying to achieve, but you are "messing it up" :)

      class AddNewMachineScreen(QWidget, Ui_Widget)

      This defines a class named AddNewMachineScreen(). And calling AddNewMachineScreen() would invoke its __init__() as I was expecting.

      from ui_addNewMachineScreen import Ui_Widget as AddNewMachineScreen

      This "redefines" AddNewMachineScreen. It now "refers to" Ui_Widget, as an "alias". It cannot also refer to the class you defined at the same time. I guess in Python this overrides the class definition. So invoking AddNewMachineScreen() now actually does Ui_Widget(), whatever that does. Hence you never create an AddNewMachineScreen or hit its __init__().

      I do not claim to understand what you are trying to do. I can say that you have absolutely no need to do an import ... as ..., that is just for aliasing. I suggest whatever you are trying to achieve you remove any such construct and start over....

      O Offline
      O Offline
      orsini29
      wrote on last edited by orsini29
      #7

      @JonB

      So my understanding was this,

      from ui_addNewMachineScreen I am importing Ui_Widget, and I want to reference this as AddNewMachineScreen within my code. Which is basically what you had explained here (below) if I am understanding correctly.

      @JonB said in Issue opening new window:

      This "redefines" AddNewMachineScreen. It now "refers to" Ui_Widget, as an "alias". It cannot also refer to the class you defined at the same time. I guess in Python this overrides the class definition. So invoking AddNewMachineScreen() nwo actually does Ui_Widget(), whatever that does.

      The reason I did this, is because if I do the following import I come across the following issue

      # This Python file uses the following encoding: utf-8
      import sys
      import openpyxl as pyxl
      import datetime
      
      from PySide6 import QtCore
      from PySide6.QtWidgets import QApplication, QWidget
      
      # Important:
      # You need to run the following command to generate the ui_form.py file
      #     pyside6-uic form.ui -o ui_form.py, or
      #     pyside2-uic form.ui -o ui_form.py
      from ui_form import Ui_Widget
      from ui_addNewMachineScreen import Ui_Widget 
      #the above import was changed from original one mentioned in post above
      
      redefinition of unused 'Ui_Widget' from line 13
      

      Which makes sense for this error, being I am importing Ui_Widget twice, on line 12 and 13.

      How would I mitigate this issue? I am new to Python within Qt, so I was wondering if you had a general skeleton that is normally followed to get this to work. Thanks in advance!

      Edit: wait a second. I am thinking to far into it. I just need to make the alias name after the "as" command, something OTHER then the class name, correct? If so, so sorry for the confusion on my part!

      Edit 2: Okay so I belive my first edit was incorrect. I guess now I am confused on how to get into the __init__ method of the AddNewMachineScreen class. Sorry, I am a Python newbie I'm sure my questions are elementary...

      Because I had changed the import/slot to the following:

      widget.py

      # This Python file uses the following encoding: utf-8
      import sys
      import openpyxl as pyxl
      import datetime
      
      from PySide6 import QtCore
      from PySide6.QtWidgets import QApplication, QWidget
      
      # Important:
      # You need to run the following command to generate the ui_form.py file
      #     pyside6-uic form.ui -o ui_form.py, or
      #     pyside2-uic form.ui -o ui_form.py
      from ui_form import Ui_Widget
      from ui_addNewMachineScreen import Ui_Widget as temp #####HERE
      
      class Widget(QWidget):
          def __init__(self, parent=None):
              super().__init__(parent)
              self.ui = Ui_Widget()
              self.ui.setupUi(self)
              self.connect_slots()
      
          def connect_slots(self):
              self.ui.addMachineButton.clicked.connect(self.add_machine_button_clicked)
              self.ui.editMachineButton.clicked.connect(self.edit_machine_button_clicked)
              self.ui.removeMachineButton.clicked.connect(self.remove_machine_button_clicked)
      
          @QtCore.Slot()
          def add_machine_button_clicked(self):
              self.local = temp()  #####HERE
              self.local_widget = QWidget()
              self.local.setupUi(self.local_widget)
              self.local_widget.show()
      

      But the __init__ still doesn't run, because the AddNewMachineScreen is never called...so would I just need to import the AddNewMachineScreen.py and then instantiate the object?

      JonBJ 1 Reply Last reply
      0
      • O orsini29

        @JonB

        So my understanding was this,

        from ui_addNewMachineScreen I am importing Ui_Widget, and I want to reference this as AddNewMachineScreen within my code. Which is basically what you had explained here (below) if I am understanding correctly.

        @JonB said in Issue opening new window:

        This "redefines" AddNewMachineScreen. It now "refers to" Ui_Widget, as an "alias". It cannot also refer to the class you defined at the same time. I guess in Python this overrides the class definition. So invoking AddNewMachineScreen() nwo actually does Ui_Widget(), whatever that does.

        The reason I did this, is because if I do the following import I come across the following issue

        # This Python file uses the following encoding: utf-8
        import sys
        import openpyxl as pyxl
        import datetime
        
        from PySide6 import QtCore
        from PySide6.QtWidgets import QApplication, QWidget
        
        # Important:
        # You need to run the following command to generate the ui_form.py file
        #     pyside6-uic form.ui -o ui_form.py, or
        #     pyside2-uic form.ui -o ui_form.py
        from ui_form import Ui_Widget
        from ui_addNewMachineScreen import Ui_Widget 
        #the above import was changed from original one mentioned in post above
        
        redefinition of unused 'Ui_Widget' from line 13
        

        Which makes sense for this error, being I am importing Ui_Widget twice, on line 12 and 13.

        How would I mitigate this issue? I am new to Python within Qt, so I was wondering if you had a general skeleton that is normally followed to get this to work. Thanks in advance!

        Edit: wait a second. I am thinking to far into it. I just need to make the alias name after the "as" command, something OTHER then the class name, correct? If so, so sorry for the confusion on my part!

        Edit 2: Okay so I belive my first edit was incorrect. I guess now I am confused on how to get into the __init__ method of the AddNewMachineScreen class. Sorry, I am a Python newbie I'm sure my questions are elementary...

        Because I had changed the import/slot to the following:

        widget.py

        # This Python file uses the following encoding: utf-8
        import sys
        import openpyxl as pyxl
        import datetime
        
        from PySide6 import QtCore
        from PySide6.QtWidgets import QApplication, QWidget
        
        # Important:
        # You need to run the following command to generate the ui_form.py file
        #     pyside6-uic form.ui -o ui_form.py, or
        #     pyside2-uic form.ui -o ui_form.py
        from ui_form import Ui_Widget
        from ui_addNewMachineScreen import Ui_Widget as temp #####HERE
        
        class Widget(QWidget):
            def __init__(self, parent=None):
                super().__init__(parent)
                self.ui = Ui_Widget()
                self.ui.setupUi(self)
                self.connect_slots()
        
            def connect_slots(self):
                self.ui.addMachineButton.clicked.connect(self.add_machine_button_clicked)
                self.ui.editMachineButton.clicked.connect(self.edit_machine_button_clicked)
                self.ui.removeMachineButton.clicked.connect(self.remove_machine_button_clicked)
        
            @QtCore.Slot()
            def add_machine_button_clicked(self):
                self.local = temp()  #####HERE
                self.local_widget = QWidget()
                self.local.setupUi(self.local_widget)
                self.local_widget.show()
        

        But the __init__ still doesn't run, because the AddNewMachineScreen is never called...so would I just need to import the AddNewMachineScreen.py and then instantiate the object?

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

        @orsini29 said in Issue opening new window:

        I just need to make the alias name after the "as" command, something OTHER then the class name, correct?

        That would be an improvement :)

        I don't know what any of your from ui_... import UI_... are about/for. I never used any such in Python (or C++) Qt programming. I don't know where you get this pattern from. I wonder whether you are trying to import/expose too much. You don't usually import UI stuff from other modules, just the non-UI-named wrapper you create for each UI form. I never encountered any of your problems (in Python), it was all straightforward.

        I am going to have to lave you for some Python expert to answer.

        O 1 Reply Last reply
        1
        • JonBJ JonB

          @orsini29 said in Issue opening new window:

          I just need to make the alias name after the "as" command, something OTHER then the class name, correct?

          That would be an improvement :)

          I don't know what any of your from ui_... import UI_... are about/for. I never used any such in Python (or C++) Qt programming. I don't know where you get this pattern from. I wonder whether you are trying to import/expose too much. You don't usually import UI stuff from other modules, just the non-UI-named wrapper you create for each UI form. I never encountered any of your problems (in Python), it was all straightforward.

          I am going to have to lave you for some Python expert to answer.

          O Offline
          O Offline
          orsini29
          wrote on last edited by orsini29
          #9

          @JonB

          Okay, thank you very much for your assistance to this point though! Much appreciated. Hopefully I can figure this out before someone else can help, if I do I will update the thread. Otherwise all assistance is appreciated!

          As for the

          from ui_ .... import .... as .....

          I believe that this statement will grab the ui_className file generated from the *.ui file, and open it up. I assume I am missing out on the pairing of this and the class itself, if I had to guess. Hopefully someone more versed in Python would be able to be of assistance.

          JonBJ 1 Reply Last reply
          0
          • O orsini29

            @JonB

            Okay, thank you very much for your assistance to this point though! Much appreciated. Hopefully I can figure this out before someone else can help, if I do I will update the thread. Otherwise all assistance is appreciated!

            As for the

            from ui_ .... import .... as .....

            I believe that this statement will grab the ui_className file generated from the *.ui file, and open it up. I assume I am missing out on the pairing of this and the class itself, if I had to guess. Hopefully someone more versed in Python would be able to be of assistance.

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

            @orsini29
            Let me just try one other explanation. Let's talk about C++, but I think exactly the same applies to Python/PyQt/PySide.

            • I have two designer files for their widgets, fred.ui & jim.ui.
            • I run uic to produce ui_fred.h & ui_jim.h.
            • I only #include "ui_fred.h" in fred.cpp, never in jim.cpp, and the same the other way round.
            • If fred.cpp wants to talk to/use jim stuff, I #include "jim.h" in fred.cpp. I do not include ui_jim.h. That is only private stuff for jim.cpp to use, and if required it writes exported wrapper functions (in jim.h) around any private stuff.

            This should apply equally from Python stuff, with imports and different file/module names. I have a feeling you are not doing this, you are trying to import private stuff from one to the other?

            O 1 Reply Last reply
            2
            • JonBJ JonB

              @orsini29
              Let me just try one other explanation. Let's talk about C++, but I think exactly the same applies to Python/PyQt/PySide.

              • I have two designer files for their widgets, fred.ui & jim.ui.
              • I run uic to produce ui_fred.h & ui_jim.h.
              • I only #include "ui_fred.h" in fred.cpp, never in jim.cpp, and the same the other way round.
              • If fred.cpp wants to talk to/use jim stuff, I #include "jim.h" in fred.cpp. I do not include ui_jim.h. That is only private stuff for jim.cpp to use, and if required it writes exported wrapper functions (in jim.h) around any private stuff.

              This should apply equally from Python stuff, with imports and different file/module names. I have a feeling you are not doing this, you are trying to import private stuff from one to the other?

              O Offline
              O Offline
              orsini29
              wrote on last edited by orsini29
              #11

              @JonB

              Yes...what you said does make sense and I feel like I am doing exactly what you are saying, and I believe it is incorrect...now I just have to figure out how to make that encapsulation (maybe the right term, maybe not), work correctly. :D

              Very helpful explanation though, with what I was doing. Made me understand it better...now to figure out how to fix this

              1 Reply Last reply
              1
              • F Offline
                F Offline
                friedemannkleint
                wrote on last edited by
                #12

                Have you seen https://doc.qt.io/qtforpython-6/tutorials/basictutorial/uifiles.html ?

                O 1 Reply Last reply
                1
                • F friedemannkleint

                  Have you seen https://doc.qt.io/qtforpython-6/tutorials/basictutorial/uifiles.html ?

                  O Offline
                  O Offline
                  orsini29
                  wrote on last edited by
                  #13

                  @friedemannkleint

                  This is very helpful, but I am having trouble getting the screen to open now.

                  I have these files

                  AddNewMachineScreen.py

                  # This Python file uses the following encoding: utf-8
                  import sys
                  from PySide6 import QtCore
                  from PySide6.QtWidgets import QApplication, QWidget
                  from ui_addNewMachineScreen import Ui_Widget
                  
                  class AddNewMachineScreen(QWidget):
                      def __init__(self):
                          super(AddNewMachineScreen, self).__init__()
                          self.ui = Ui_Widget()
                          self.ui.setupUi(self)
                          self.connect_slots()
                  
                      def connect_slots(self):
                          print("here1")
                          self.ui.calibrateCheck.stateChanged.connect(self.calibrate_check_state_changed)
                  
                      @QtCore.Slot()
                      def calibrate_check_state_changed(self, int):
                          print("here2")
                  
                  if __name__ == "__main__":
                      app = QApplication(sys.argv)
                      print("here")
                      add_machine = AddNewMachineScreen()
                      add_machine.show()
                      sys.exit(app.exec())
                  

                  widget.py (only showing the slot function, as it is all that matters I believe being the button click slot is what is supposed to open the page)

                  import AddNewMachineScreen as anms
                  
                      @QtCore.Slot()
                      def add_machine_button_clicked(self):
                          anms.AddNewMachineScreen()
                  

                  It has to be an issue of only calling the constructor here, and not actually saving it and showing the UI screen itself, correct? I am going to look a bit more into this, because there is definitely something super simple I am missing and I know I will kick myself for it. Thanks a lot for the link!

                  JonBJ 1 Reply Last reply
                  0
                  • O orsini29

                    @friedemannkleint

                    This is very helpful, but I am having trouble getting the screen to open now.

                    I have these files

                    AddNewMachineScreen.py

                    # This Python file uses the following encoding: utf-8
                    import sys
                    from PySide6 import QtCore
                    from PySide6.QtWidgets import QApplication, QWidget
                    from ui_addNewMachineScreen import Ui_Widget
                    
                    class AddNewMachineScreen(QWidget):
                        def __init__(self):
                            super(AddNewMachineScreen, self).__init__()
                            self.ui = Ui_Widget()
                            self.ui.setupUi(self)
                            self.connect_slots()
                    
                        def connect_slots(self):
                            print("here1")
                            self.ui.calibrateCheck.stateChanged.connect(self.calibrate_check_state_changed)
                    
                        @QtCore.Slot()
                        def calibrate_check_state_changed(self, int):
                            print("here2")
                    
                    if __name__ == "__main__":
                        app = QApplication(sys.argv)
                        print("here")
                        add_machine = AddNewMachineScreen()
                        add_machine.show()
                        sys.exit(app.exec())
                    

                    widget.py (only showing the slot function, as it is all that matters I believe being the button click slot is what is supposed to open the page)

                    import AddNewMachineScreen as anms
                    
                        @QtCore.Slot()
                        def add_machine_button_clicked(self):
                            anms.AddNewMachineScreen()
                    

                    It has to be an issue of only calling the constructor here, and not actually saving it and showing the UI screen itself, correct? I am going to look a bit more into this, because there is definitely something super simple I am missing and I know I will kick myself for it. Thanks a lot for the link!

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

                    @orsini29 said in Issue opening new window:

                    It has to be an issue of only calling the constructor here, and not actually saving it and showing the UI screen itself, correct?

                    Well, yes.

                    • anms.AddNewMachineScreen() creates a new AddNewMachineScreen instance, which calls its constructor. That's all it does: nothing here shows the widget.

                    • Furthermore: you do not assign the returned instance to anything. In C++ if you just write new AddNewMachineScreen(); (which would be the equivalent) that would leave an (unreferenced) instance lying around, forever. But Python reference counts objects, and destroys them when no in-scope references remain. anms.AddNewMachineScreen() creates an instance, and then as soon as that statement completes destroys it because nothing is referencing it. You will need to assign it to something. And if you use a local variable that will go at the end of that function. If you want the widget to persist you will likely want to assign it to a class member variable in widget.py, or pass it a parent so that it lives as long as the parent.

                    O 1 Reply Last reply
                    1
                    • JonBJ JonB

                      @orsini29 said in Issue opening new window:

                      It has to be an issue of only calling the constructor here, and not actually saving it and showing the UI screen itself, correct?

                      Well, yes.

                      • anms.AddNewMachineScreen() creates a new AddNewMachineScreen instance, which calls its constructor. That's all it does: nothing here shows the widget.

                      • Furthermore: you do not assign the returned instance to anything. In C++ if you just write new AddNewMachineScreen(); (which would be the equivalent) that would leave an (unreferenced) instance lying around, forever. But Python reference counts objects, and destroys them when no in-scope references remain. anms.AddNewMachineScreen() creates an instance, and then as soon as that statement completes destroys it because nothing is referencing it. You will need to assign it to something. And if you use a local variable that will go at the end of that function. If you want the widget to persist you will likely want to assign it to a class member variable in widget.py, or pass it a parent so that it lives as long as the parent.

                      O Offline
                      O Offline
                      orsini29
                      wrote on last edited by orsini29
                      #15

                      @JonB

                      Yes, you were right and as was I. Cannot believe I didn't think of this immediately.

                      Everything is fixed, thank you for your assistance!

                      widget.py

                      class Widget(QWidget):
                          def __init__(self, parent=None):
                              super().__init__(parent)
                              self.ui = Ui_Widget()
                              self.ui.setupUi(self)
                              self.connect_slots()
                              self.add_machine_screen = anms.AddNewMachineScreen()
                      
                          def connect_slots(self):
                              self.ui.addMachineButton.clicked.connect(self.add_machine_button_clicked)
                      
                          @QtCore.Slot()
                          def add_machine_button_clicked(self):
                              self.add_machine_screen.show()
                      

                      AddNewMachineScreen.py

                      class AddNewMachineScreen(QWidget):
                          def __init__(self):
                              super(AddNewMachineScreen, self).__init__()
                              self.ui = Ui_Widget()
                              self.ui.setupUi(self)
                              self.connect_slots()
                      
                          def connect_slots(self):
                              print("here1")
                              self.ui.calibrateCheck.stateChanged.connect(self.calibrate_check_state_changed)
                      
                      1 Reply Last reply
                      0
                      • O orsini29 has marked this topic as solved on

                      • Login

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