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

closeEvent not running

Scheduled Pinned Locked Moved Solved Qt for Python
36 Posts 3 Posters 8.6k 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