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. closeEvent not running
Qt 6.11 is out! See what's new in the release blog

closeEvent not running

Scheduled Pinned Locked Moved Solved Qt for Python
36 Posts 3 Posters 15.8k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    DoubleFelix
    wrote on last edited by
    #1

    I have my base class here:

    class MyWindow:
        def __init__(self):
            self.window = loadUiFile(os.path.join(os.path.dirname(__file__), "window.ui"))
    
        def closeEvent(self, event):
            print("closing...")
            event.accept()
    

    but it does not run. I tried having the class inherit QWindow and QWidget and nothing.
    loadUiFile just returns a read UI file like so:

    def loadUiFile(file_path):
        file = QFile(file_path)
        file.open(QFile.ReadOnly)
        loader = QUiLoader()
        window = loader.load(file)
        return window
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet

      Your MyWindow is just a Python object subclass hence it has no closeEvent.

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

      1 Reply Last reply
      1
      • D Offline
        D Offline
        DoubleFelix
        wrote on last edited by
        #3

        What do I need to add to it so that it has that method?

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          It should inherit QWidget and but your dynamically loaded UI in a layout set on it.

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

          1 Reply Last reply
          0
          • D Offline
            D Offline
            DoubleFelix
            wrote on last edited by
            #5

            Do you mean loadUiType? I tried using that but it kept saying Ui_mywindow was not defined

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              No, as I wrote your MyWindow.

              You should start by following a tutorial before trying the dynamic UI route like that. Especially if you want to have custom methods.

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

              1 Reply Last reply
              2
              • D Offline
                D Offline
                DoubleFelix
                wrote on last edited by
                #7

                I attempted to use loadUiType to get the QWindow stuff, but it raises this error: NameError: name 'Ui_MainWindow' is not defined
                Code is below:

                window, qwindow = loadUiType(os.path.join(os.path.dirname(__file__), "window.ui"))
                class MyWindow(window, qwindow):```
                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  That's wrong.

                  Please follow the example shown in QUiLoader documentation.

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

                  1 Reply Last reply
                  1
                  • D Offline
                    D Offline
                    DoubleFelix
                    wrote on last edited by DoubleFelix
                    #9

                    I followed the example and got this:

                    class MyWindow(QWidget):
                        def __init__(self):
                            super(QWidget, self).__init__()
                            file = QFile(os.path.join(os.path.dirname(__file__), "window.ui"))
                            file.open(QFile.ReadOnly)
                            loader = QUiLoader()
                            window = loader.load(file, self)
                            #window = loadUiFile(os.path.join(os.path.dirname(__file__), "window.ui"))
                            layout = QVBoxLayout()
                            layout.addWidget(window)
                            self.setLayout(layout)
                    

                    It raises the error TypeError: PySide6.QtCore.QObject isn't a direct base class of MyWindow
                    I'm not sure if I read it wrong or if I'm looking at the wrong spot

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      What if your replace:
                      @DoubleFelix said in closeEvent not running:

                      super(QWidget, self).init()

                      with:

                      super().__init__()
                      

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

                      1 Reply Last reply
                      0
                      • D Offline
                        D Offline
                        DoubleFelix
                        wrote on last edited by
                        #11

                        That fixes that error, but now when I try to access elements, it says they don't exist.
                        self.my_button.clicked.connect(self.button_clicked) raises AttributeError: 'MyWindow' object has no attribute 'my_button'

                        JonBJ SGaistS 2 Replies Last reply
                        0
                        • D DoubleFelix

                          That fixes that error, but now when I try to access elements, it says they don't exist.
                          self.my_button.clicked.connect(self.button_clicked) raises AttributeError: 'MyWindow' object has no attribute 'my_button'

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

                          @DoubleFelix
                          I read that you're supposed to do it via:

                          super(MyWindow, self).__init__()
                          

                          Though whether that equates to

                          super().__init__()
                          

                          I don't know.

                          1 Reply Last reply
                          0
                          • D Offline
                            D Offline
                            DoubleFelix
                            wrote on last edited by
                            #13

                            @JonB I still get the same error if I modify it to be that

                            1 Reply Last reply
                            1
                            • D DoubleFelix

                              That fixes that error, but now when I try to access elements, it says they don't exist.
                              self.my_button.clicked.connect(self.button_clicked) raises AttributeError: 'MyWindow' object has no attribute 'my_button'

                              SGaistS Offline
                              SGaistS Offline
                              SGaist
                              Lifetime Qt Champion
                              wrote on last edited by
                              #14

                              @DoubleFelix said in closeEvent not running:

                              That fixes that error, but now when I try to access elements, it says they don't exist.
                              self.my_button.clicked.connect(self.button_clicked) raises AttributeError: 'MyWindow' object has no attribute 'my_button'

                              Because my_button is something that belongs to the widget you created with designer ? If so it's your "window" variable that will have access to it.

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

                              1 Reply Last reply
                              1
                              • D Offline
                                D Offline
                                DoubleFelix
                                wrote on last edited by
                                #15

                                I tried switching it to window and now the closeEvent still does nothing. I have this now:

                                class TexasHoldEmServerWindow(QWidget):
                                    def __init__(self):
                                        super(TexasHoldEmServerWindow, self).__init__()
                                        file = QFile(os.path.join(os.path.dirname(__file__), "window.ui"))
                                        file.open(QFile.ReadOnly)
                                        loader = QUiLoader()
                                        window = loader.load(file, self)
                                        self.window = loadUiFile(os.path.join(os.path.dirname(__file__), "window.ui"))
                                        layout = QVBoxLayout()
                                        layout.addWidget(window)
                                        self.setLayout(layout)
                                
                                        self.window.start_game_button.clicked.connect(self.start_game)
                                
                                    def closeEvent(self, event):
                                        print("PLS WORK")
                                        event.accept()
                                

                                No errors, but it still doesn't run the function

                                1 Reply Last reply
                                0
                                • SGaistS Offline
                                  SGaistS Offline
                                  SGaist
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #16

                                  You should learn how inheritance work.

                                  The proper way to add closeEvent handling to your Designer based class is to create a proper class i.e. you cannot use QUiLoader for that.

                                  Since you are using Python, you can cheat and monkey patch your window object (you really should name your variable in a more meaningful way).

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

                                  1 Reply Last reply
                                  1
                                  • D Offline
                                    D Offline
                                    DoubleFelix
                                    wrote on last edited by
                                    #17

                                    I do have a different name, I just named it differently for convenience. Although I guess it's less convenient than I thought.
                                    I think I understand how inheritance works, I just don't know how I'd make this a "proper" class while still loading from a UI. I guess I just don't know what I need to inherit to get closeEvent().

                                    JonBJ 1 Reply Last reply
                                    0
                                    • D DoubleFelix

                                      I do have a different name, I just named it differently for convenience. Although I guess it's less convenient than I thought.
                                      I think I understand how inheritance works, I just don't know how I'd make this a "proper" class while still loading from a UI. I guess I just don't know what I need to inherit to get closeEvent().

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

                                      @DoubleFelix
                                      I don't mean to open up a box of asps, but...

                                      Are you wedded to using QUiLoader/loadUiFile? This reads the .ui file generated from Qt Designer at runtime. It does not lend itself to subclassing, I think. And I believe that is what @SGaist is referring to

                                      The proper way to add closeEvent handling to your Designer based class is to create a proper class i.e. you cannot use QUiLoader for that.

                                      though I stand to be corrected.

                                      If that is so, read on:

                                      Most C++ Qt-ers will instead run the uic tool at compilation stage to generate the source code for a derived class, and use that in their project. This gives better control and compile-time help, IMHO.

                                      You can do the same from Python, if you wish. Exact depends on whether you are PyQt5 or PySide2/6, but principle is the same. They supply an equivalent pyuic tool, to read a .ui file and produce a Python class from it, which you then import.

                                      You can then subclass from that and define your own def closeEvent override.

                                      Read Option A: Generating a Python class. And compare against your way, which is Option B: Loading it directly. See which you prefer.

                                      Hope this helps.

                                      1 Reply Last reply
                                      1
                                      • D Offline
                                        D Offline
                                        DoubleFelix
                                        wrote on last edited by
                                        #19

                                        I wasn't aware that is what uic did. I will try that out! Is there a tool that can auto convert this stuff or do I need to do it with every change?

                                        JonBJ 1 Reply Last reply
                                        0
                                        • D DoubleFelix

                                          I wasn't aware that is what uic did. I will try that out! Is there a tool that can auto convert this stuff or do I need to do it with every change?

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

                                          @DoubleFelix
                                          You do have run the pyuic every time you re-save the .ui file. When using C++ inside Creator the build process will do that automatically just before recompiling. I don't know whether there is anything similar when you use Python/PySide inside Creator, or whether you have to do it by hand. You should Google around.

                                          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