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
Forum Updated to NodeBB v4.3 + New Features

Issue opening new window

Scheduled Pinned Locked Moved Solved Qt for Python
15 Posts 3 Posters 2.0k 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 Offline
    O Offline
    orsini29
    wrote on last edited by orsini29
    #1

    Hello all,

    I have done a lot of programming with C++ and Qt, and finally ventured into the Python/Qt world. I am using PySide6 currently for this application.

    I am trying to have a QPushButton open a new window upon click, and I have this part working with the following code:

    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 AddNewMachineScreen
    
    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)
    
        @QtCore.Slot()
        def add_machine_button_clicked(self):
            self.local = AddNewMachineScreen()
            self.local_widget = QWidget()
            self.local.setupUi(self.local_widget)
            self.local_widget.show()
    
    def main():
        populate_licenses_available()
        populate_machines_in_year_label()
        populate_not_shipped_machines()
    
    def find_year_in_workbook(col: str):
        # Grabbing the current year
        year = datetime.date.today().year
    
        # Grabbing the excel workbook/worksheet
        workbook = pyxl.load_workbook("workbook.xlsx", data_only = True)
        worksheet = workbook["worksheet"]
    
        # Setting variables for while loop
        found = False
        row = 1
    
        # Iterating over rows and reading Column R to find the specific year
        while not found:
            if worksheet[col + str(row)].value == str(year) + " Count":
                found = True
            else:
                row += 5
    
        return row
    
    def populate_licenses_available():
        # Grabbing the excel workbook/worksheet
        workbook = pyxl.load_workbook("workbook.xlsx", data_only = True)
        worksheet = workbook["worksheet"]
    
        # Grabbing the row which the current year is located
        row = find_year_in_workbook("R")
    
        # Setting the label based upon the License Avalaible value
        widget.ui.licenseAnsLabel.setText(str(worksheet["S" + str(row+3)].value))
    
    def populate_not_shipped_machines():
        # Local variables
        amt_not_shipped = 0
    
        # Grabbing the excel workbook/worksheet
        workbook = pyxl.load_workbook("workbook.xlsx", data_only = True)
        worksheet = workbook["worksheet"]
    
        # Iterating over the "E" column
        for row in worksheet.iter_rows():
            if row[4].value == "n":
                amt_not_shipped += 1
    
        # Setting the label based upon the amount of machines not shipped
        widget.ui.notShippedAnsLabel.setText(str(amt_not_shipped))
    
    def populate_machines_in_year_label():
        # Grabbing the current year
        year = datetime.date.today().year
        widget.ui.machinesInYearLabel.setText("MACHINES IN " + str(year))
    
        # Grabbing the excel workbook/worksheet
        workbook = pyxl.load_workbook("workbook.xlsx", data_only = True)
        worksheet = workbook["worksheet"]
    
        # Grabbing the row which the current year is located
        row = find_year_in_workbook("R")
    
        # Setting the label based upon the Used Licenses value
        widget.ui.machinesInYearAnsLabel.setText(str(worksheet["S" + str(row+2)].value))
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        widget = Widget()
        widget.show()
        main()
        sys.exit(app.exec())
    
    

    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, Ui_Widget):
        def __init__(self):
            super().__init__()
            self.setupUi(self)
            print("here0")
            self.connect_slots(self)
    
        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)
        add_machine = AddNewMachineScreen()
        add_machine.show()
        print("here")
        sys.exit(app.exec())
    

    My issue is, that when the AddNewMachineScreen window opens, the slots do not connect, as I can see by the messages not being printed to the console. I was curious if someone can point me in the right direction?

    Am I not opening the secondary window correctly? Maybe it is an issue with what I am passing to the __init__(self) method within the AddNewMachineScreen.py file? Maybe I need to pass the parent window as a parameter?

    Thank you in advance for any assistance, or pointers as to what I am doing wrong so far!

    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 Online
      JonBJ Online
      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
      • O orsini29

        Hello all,

        I have done a lot of programming with C++ and Qt, and finally ventured into the Python/Qt world. I am using PySide6 currently for this application.

        I am trying to have a QPushButton open a new window upon click, and I have this part working with the following code:

        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 AddNewMachineScreen
        
        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)
        
            @QtCore.Slot()
            def add_machine_button_clicked(self):
                self.local = AddNewMachineScreen()
                self.local_widget = QWidget()
                self.local.setupUi(self.local_widget)
                self.local_widget.show()
        
        def main():
            populate_licenses_available()
            populate_machines_in_year_label()
            populate_not_shipped_machines()
        
        def find_year_in_workbook(col: str):
            # Grabbing the current year
            year = datetime.date.today().year
        
            # Grabbing the excel workbook/worksheet
            workbook = pyxl.load_workbook("workbook.xlsx", data_only = True)
            worksheet = workbook["worksheet"]
        
            # Setting variables for while loop
            found = False
            row = 1
        
            # Iterating over rows and reading Column R to find the specific year
            while not found:
                if worksheet[col + str(row)].value == str(year) + " Count":
                    found = True
                else:
                    row += 5
        
            return row
        
        def populate_licenses_available():
            # Grabbing the excel workbook/worksheet
            workbook = pyxl.load_workbook("workbook.xlsx", data_only = True)
            worksheet = workbook["worksheet"]
        
            # Grabbing the row which the current year is located
            row = find_year_in_workbook("R")
        
            # Setting the label based upon the License Avalaible value
            widget.ui.licenseAnsLabel.setText(str(worksheet["S" + str(row+3)].value))
        
        def populate_not_shipped_machines():
            # Local variables
            amt_not_shipped = 0
        
            # Grabbing the excel workbook/worksheet
            workbook = pyxl.load_workbook("workbook.xlsx", data_only = True)
            worksheet = workbook["worksheet"]
        
            # Iterating over the "E" column
            for row in worksheet.iter_rows():
                if row[4].value == "n":
                    amt_not_shipped += 1
        
            # Setting the label based upon the amount of machines not shipped
            widget.ui.notShippedAnsLabel.setText(str(amt_not_shipped))
        
        def populate_machines_in_year_label():
            # Grabbing the current year
            year = datetime.date.today().year
            widget.ui.machinesInYearLabel.setText("MACHINES IN " + str(year))
        
            # Grabbing the excel workbook/worksheet
            workbook = pyxl.load_workbook("workbook.xlsx", data_only = True)
            worksheet = workbook["worksheet"]
        
            # Grabbing the row which the current year is located
            row = find_year_in_workbook("R")
        
            # Setting the label based upon the Used Licenses value
            widget.ui.machinesInYearAnsLabel.setText(str(worksheet["S" + str(row+2)].value))
        
        if __name__ == "__main__":
            app = QApplication(sys.argv)
            widget = Widget()
            widget.show()
            main()
            sys.exit(app.exec())
        
        

        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, Ui_Widget):
            def __init__(self):
                super().__init__()
                self.setupUi(self)
                print("here0")
                self.connect_slots(self)
        
            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)
            add_machine = AddNewMachineScreen()
            add_machine.show()
            print("here")
            sys.exit(app.exec())
        

        My issue is, that when the AddNewMachineScreen window opens, the slots do not connect, as I can see by the messages not being printed to the console. I was curious if someone can point me in the right direction?

        Am I not opening the secondary window correctly? Maybe it is an issue with what I am passing to the __init__(self) method within the AddNewMachineScreen.py file? Maybe I need to pass the parent window as a parameter?

        Thank you in advance for any assistance, or pointers as to what I am doing wrong so far!

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

        @orsini29 said in Issue opening new window:

        My issue is, that when the AddNewMachineScreen window opens, the slots do not connect, as I can see by the messages not being printed to the console

        I don't understand this. As soon as self.local = AddNewMachineScreen() executes (do you get there) that would call AddNewMachineScreen.__init__(). At minimum I would expect that to print("here0") and print("here1") at least?

        Back in widget.py after showing widget you go main(). What is that? You don't define it. I don't know what it does or why you call it. I have never seen a Python Qt program, whether PySide or PyQt, call or define it.

        O 1 Reply Last reply
        0
        • JonBJ JonB

          @orsini29 said in Issue opening new window:

          My issue is, that when the AddNewMachineScreen window opens, the slots do not connect, as I can see by the messages not being printed to the console

          I don't understand this. As soon as self.local = AddNewMachineScreen() executes (do you get there) that would call AddNewMachineScreen.__init__(). At minimum I would expect that to print("here0") and print("here1") at least?

          Back in widget.py after showing widget you go main(). What is that? You don't define it. I don't know what it does or why you call it. I have never seen a Python Qt program, whether PySide or PyQt, call or define it.

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

          @JonB

          Sorry about excluding main(), this was just a function to run a couple of functions in sequential order. Should this have just been done in the constructor rather than a separate function for it like I did?

          I updated widget.py above to include the function, once again sorry for omitting it! It is just functionality I had left out in the question from the overall program itself, being the issue arises without it. Although I forgot to omit the main() function call like you had said, so I understand the confusion.

          I as well am confused, but once I press addMachineButton it opens ui_addNewMachineScreen, and nothing prints, nor does the checkbox slot ever connect, because nothing prints when I check the QCheckBox calibrateCheck

          JonBJ 1 Reply Last reply
          0
          • O orsini29

            @JonB

            Sorry about excluding main(), this was just a function to run a couple of functions in sequential order. Should this have just been done in the constructor rather than a separate function for it like I did?

            I updated widget.py above to include the function, once again sorry for omitting it! It is just functionality I had left out in the question from the overall program itself, being the issue arises without it. Although I forgot to omit the main() function call like you had said, so I understand the confusion.

            I as well am confused, but once I press addMachineButton it opens ui_addNewMachineScreen, and nothing prints, nor does the checkbox slot ever connect, because nothing prints when I check the QCheckBox calibrateCheck

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

            @orsini29 said in Issue opening new window:

            I as well am confused, but once I press addMachineButton it opens ui_addNewMachineScreen, and nothing prints

            Why don't you step through in debugger? I see def add_machine_button_clicked(self): calling self.local = AddNewMachineScreen(). In class AddNewMachineScreen(QWidget, Ui_Widget) function __init__() I see print("here0") as the 3rd statement. I would expect that to print? Put it as first statement?

            O 1 Reply Last reply
            0
            • JonBJ JonB

              @orsini29 said in Issue opening new window:

              I as well am confused, but once I press addMachineButton it opens ui_addNewMachineScreen, and nothing prints

              Why don't you step through in debugger? I see def add_machine_button_clicked(self): calling self.local = AddNewMachineScreen(). In class AddNewMachineScreen(QWidget, Ui_Widget) function __init__() I see print("here0") as the 3rd statement. I would expect that to print? Put it as first statement?

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

              @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 1 Reply Last reply
              0
              • 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 Online
                JonBJ Online
                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 Online
                    JonBJ Online
                    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 Online
                        JonBJ Online
                        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 Online
                                JonBJ Online
                                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