Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Language Bindings
  4. closeEvent not working

closeEvent not working

Scheduled Pinned Locked Moved Unsolved Language Bindings
32 Posts 8 Posters 19.6k 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.
  • Z Offline
    Z Offline
    ZioLupo
    wrote on last edited by aha_1980
    #1

    I have the following code but closeEvent is never reached.
    I need to intercept when someone close the window and I would like to know how to do.
    Thank you

    import sys
     
    from PySide2 import QtUiTools
    from PySide2 import QtCore, QtGui, QtWidgets
    
    
    
    class Form(QtWidgets.QMainWindow):
     
        def __init__(self, ui_file, parent=None):
            super(Form, self).__init__(parent)
            self.ui=QtUiTools.QUiLoader().load(ui_file)
            self.ui.show()
    
        def closeEvent(self, event):
            print("I want to exit!")
         
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
        form = Form('mainwindow.ui')
        sys.exit(app.exec_())
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      You're not showing a Form instance but its ui member variable.

      remove self.ui.show() and add form.show() in your __main__ code.

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

      Z 1 Reply Last reply
      1
      • SGaistS SGaist

        Hi and welcome to devnet,

        You're not showing a Form instance but its ui member variable.

        remove self.ui.show() and add form.show() in your __main__ code.

        Z Offline
        Z Offline
        ZioLupo
        wrote on last edited by
        #3

        @SGaist , my code was a workaround to another problem.
        If you do what you suggested (it was my first choice), the windows will be empty, no widgets will appear.
        It works if you define the widgets one by one inside the code, but if you are loading them with QtUiTools is not working.
        A mistery for me.

        Thats why i changed the code. I can put the call to show() in the main but calling "ui": form.ui.show().
        THis is working but closeEvent is not reachable.

        I'm attaching two pictures where you can see both codes and results.
        One is showing the widgets but closeEvent is not working, the other is not showing the widgets but closeEvent is working.

        Thank for your help
        0_1530686378193_closeEvent KO.png
        0_1530686392696_empty.png

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

          Because your not using QUiloader correctly. See the documentation of the class. The example code shows that once the ui file has been loaded, the resulting widget is put in a layout that is applied to the "container widget".

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

          Z 1 Reply Last reply
          1
          • SGaistS SGaist

            Because your not using QUiloader correctly. See the documentation of the class. The example code shows that once the ui file has been loaded, the resulting widget is put in a layout that is applied to the "container widget".

            Z Offline
            Z Offline
            ZioLupo
            wrote on last edited by
            #5

            @SGaist
            mmmhhhh.... welll... interesting... it means that the real problem of my code is in another place.
            I was able to write a running code but I would like to clarify better...

            class Form(QtWidgets.QMainWindow):
             
                def __init__(self, ui_file, parent=None):
                    super(Form, self).__init__(parent)
                    self.ui=QtUiTools.QUiLoader().load(ui_file)
                    layout = QtWidgets.QVBoxLayout()
                    layout.addWidget(self.ui)
                    self.setLayout(layout)
            

            This code "seems" equal to the one of the documentation (translating from C++ to python) and is not working.
            It's not working because in the class declaration I'm inheriting from QMainWindow as I was doing in PyQt5.
            If I change the code from QMainWindow to QWidget it's working but I'm loosing all the setting I did in Designer releted to the main window.

            Maybe there is something that I don't understand yet!

            Thank you

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

              You should have an error printed.

              QMainWindow already has a layout that does all the neat things like handling of toolbars and dock widgets. Therefore you would need to set your loaded widget as central widget.

              By the way, why use QUiLoader rather than pyuic ?

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

              Z 1 Reply Last reply
              0
              • SGaistS SGaist

                You should have an error printed.

                QMainWindow already has a layout that does all the neat things like handling of toolbars and dock widgets. Therefore you would need to set your loaded widget as central widget.

                By the way, why use QUiLoader rather than pyuic ?

                Z Offline
                Z Offline
                ZioLupo
                wrote on last edited by
                #7

                @SGaist
                As far as I know pyuic is not included in PySide2.

                Regarding setting the loaded widget as central widget I will investigate

                ewerybodyE 1 Reply Last reply
                0
                • Z Offline
                  Z Offline
                  ZioLupo
                  wrote on last edited by
                  #8

                  @SGaist
                  I investigate further...
                  first of all sorry for the misunderstanding on pyuic. Yes it present in PySide2 but I would prefer to load directly the ui from file.

                  Now my code is the following:

                  class Form(QtWidgets.QMainWindow):
                   
                      def __init__(self, ui_file, parent=None):
                          super(Form, self).__init__(parent)
                          self.ui=QtUiTools.QUiLoader().load(ui_file)
                          self.setCentralWidget(self.ui)
                  

                  ...and surprising it seems to work. as far as I was able to test. It seems that only window size is lost with this workaround.
                  I'm speaking of workaround because I'm just substituting the central widget... so menubar, statusbar,... they should not work if my understanding of the following picture is correct:
                  0_1530697169009_central.png
                  but instead they are present!
                  So maybe my problem is not completely solve but I think we are not far from a solution

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

                    But why are you using a QMainWindow as "holder" widget ?

                    From a quick look, there should be something like a pyside2-uic command somewhere.

                    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
                    • Z Offline
                      Z Offline
                      ZioLupo
                      wrote on last edited by
                      #10

                      Because I don't know what to do.
                      In PyQt5 I was doing something like that:

                      Ui_MainWindow = uic.loadUiType("mainwindow.ui")[0] 
                      

                      and then

                      class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
                          def __init__(self, parent=None):
                              super(MainWindow, self).__init__(parent)
                              self.ui = Ui_MainWindow()
                              self.ui.setupUi(self)
                      

                      But this is not working with PySide2.

                      If you can share a PySyde2 working code it would be really appreciated.
                      Thank you

                      JonBJ 1 Reply Last reply
                      0
                      • Z ZioLupo

                        Because I don't know what to do.
                        In PyQt5 I was doing something like that:

                        Ui_MainWindow = uic.loadUiType("mainwindow.ui")[0] 
                        

                        and then

                        class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
                            def __init__(self, parent=None):
                                super(MainWindow, self).__init__(parent)
                                self.ui = Ui_MainWindow()
                                self.ui.setupUi(self)
                        

                        But this is not working with PySide2.

                        If you can share a PySyde2 working code it would be really appreciated.
                        Thank you

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

                        @ZioLupo
                        Purely OOI, while you are waiting for an answer, may I ask you: I use PyQt and am very happy with it, why are you moving over to PySide instead?

                        Z 1 Reply Last reply
                        0
                        • JonBJ JonB

                          @ZioLupo
                          Purely OOI, while you are waiting for an answer, may I ask you: I use PyQt and am very happy with it, why are you moving over to PySide instead?

                          Z Offline
                          Z Offline
                          ZioLupo
                          wrote on last edited by
                          #12

                          @JonB
                          Well... it seems to me that PySide2 will be the "official" binding for Python.
                          IMHO it should mean more support... but maybe I'm completely wrong!

                          JonBJ 1 Reply Last reply
                          0
                          • Z ZioLupo

                            @JonB
                            Well... it seems to me that PySide2 will be the "official" binding for Python.
                            IMHO it should mean more support... but maybe I'm completely wrong!

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

                            @ZioLupo
                            Well, I get any PyQt support I need via pyqt@riverbankcomputing.com mailing list.

                            Again OOI, for my reference, how much work are you finding you need to do to convert PyQt(5) to PySide? (Sorry if I'm hijacking thread, I won't ask another question...!)

                            1 Reply Last reply
                            0
                            • Z Offline
                              Z Offline
                              ZioLupo
                              wrote on last edited by
                              #14

                              It was done in a snapshot.
                              Honestly speaking I ported a couple of very small app in a snapshot. Search & Replace is your friend.
                              The only problem I had was with UI files.
                              But the Pyside2 loader is returning an istance, not a class... so I believeI have to think differently.
                              Moreover it's not my job, I'm an old C programmer shocked by the beauty of python... so maybe I don't have to loose time and keep everythink in PyQt5 ;-)

                              JonBJ 1 Reply Last reply
                              0
                              • Z ZioLupo

                                It was done in a snapshot.
                                Honestly speaking I ported a couple of very small app in a snapshot. Search & Replace is your friend.
                                The only problem I had was with UI files.
                                But the Pyside2 loader is returning an istance, not a class... so I believeI have to think differently.
                                Moreover it's not my job, I'm an old C programmer shocked by the beauty of python... so maybe I don't have to loose time and keep everythink in PyQt5 ;-)

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

                                @ZioLupo I'm an old C programmer shocked by the ugliness of python!!

                                ewerybodyE 1 Reply Last reply
                                -1
                                • JonBJ JonB

                                  @ZioLupo I'm an old C programmer shocked by the ugliness of python!!

                                  ewerybodyE Offline
                                  ewerybodyE Offline
                                  ewerybody
                                  wrote on last edited by
                                  #16

                                  @ZioLupo what Python version are you using?
                                  I currently have no problems with 3.6.5 + PySide2 but my apps never close on the latest Python 3.7.

                                  1 Reply Last reply
                                  0
                                  • Z ZioLupo

                                    @SGaist
                                    As far as I know pyuic is not included in PySide2.

                                    Regarding setting the loaded widget as central widget I will investigate

                                    ewerybodyE Offline
                                    ewerybodyE Offline
                                    ewerybody
                                    wrote on last edited by
                                    #17

                                    @ZioLupo said in closeEvent not working:

                                    As far as I know pyuic is not included in PySide2.

                                    its pyside2uic!
                                    I do from pyside2uic import compileUi , compile my ui-files whenever changed. and do:

                                        self.ui = compiled_ui.Ui_Form()
                                        self.ui.setupUi(self.some_main_widget)
                                    
                                    Z 1 Reply Last reply
                                    0
                                    • SaelythS Offline
                                      SaelythS Offline
                                      Saelyth
                                      wrote on last edited by Saelyth
                                      #18

                                      I was porting my code of a working program from PyQt5 to PySide2 and found the same issue:

                                      def closeEvent(self, event):
                                          """Write window size and position to config file"""
                                          ini_options.setValue("menu_size", self.ui.size())
                                          ini_options.setValue("menu_position", self.ui.pos())
                                          event.accept()
                                      
                                      def eventFilter(self, target, event):
                                          print(event.type())
                                      

                                      I am using two Tabs and this was the result of me playing with the tabs. These are the only events printed:

                                      PySide2.QtCore.QEvent.Type.PolishRequest
                                      PySide2.QtCore.QEvent.Type.Move
                                      PySide2.QtCore.QEvent.Type.Resize
                                      PySide2.QtCore.QEvent.Type.Show
                                      PySide2.QtCore.QEvent.Type.ShowToParent
                                      PySide2.QtCore.QEvent.Type.UpdateLater
                                      PySide2.QtCore.QEvent.Type.Paint
                                      PySide2.QtCore.QEvent.Type.WindowDeactivate
                                      PySide2.QtCore.QEvent.Type.Hide
                                      

                                      closeEvent is never printed when I close the window. Shouldn't be somewhere after WindowDeactivate and before Hide?

                                      If I just open the software and close it without playing with the tabs, them the events are:

                                      PySide2.QtCore.QEvent.Type.PolishRequest
                                      PySide2.QtCore.QEvent.Type.Destroy
                                      

                                      I don't get why Destroy doesn't appears if I just switch to one tab to another (on the same MainWindow widget). Is the eventFilter bugged and it doesn't receives all the events?

                                      Z 1 Reply Last reply
                                      0
                                      • ewerybodyE ewerybody

                                        @ZioLupo said in closeEvent not working:

                                        As far as I know pyuic is not included in PySide2.

                                        its pyside2uic!
                                        I do from pyside2uic import compileUi , compile my ui-files whenever changed. and do:

                                            self.ui = compiled_ui.Ui_Form()
                                            self.ui.setupUi(self.some_main_widget)
                                        
                                        Z Offline
                                        Z Offline
                                        ZioLupo
                                        wrote on last edited by
                                        #19

                                        @ewerybody
                                        As I wrote some message after, yes there is -of course - pyside2-uic!
                                        But I don't like to use it.
                                        Using it solve all of my problems because it produce a class and with the class I can do what I want (inheriting from it, for example).

                                        But I would like to avoid to use it

                                        ewerybodyE 1 Reply Last reply
                                        0
                                        • SaelythS Saelyth

                                          I was porting my code of a working program from PyQt5 to PySide2 and found the same issue:

                                          def closeEvent(self, event):
                                              """Write window size and position to config file"""
                                              ini_options.setValue("menu_size", self.ui.size())
                                              ini_options.setValue("menu_position", self.ui.pos())
                                              event.accept()
                                          
                                          def eventFilter(self, target, event):
                                              print(event.type())
                                          

                                          I am using two Tabs and this was the result of me playing with the tabs. These are the only events printed:

                                          PySide2.QtCore.QEvent.Type.PolishRequest
                                          PySide2.QtCore.QEvent.Type.Move
                                          PySide2.QtCore.QEvent.Type.Resize
                                          PySide2.QtCore.QEvent.Type.Show
                                          PySide2.QtCore.QEvent.Type.ShowToParent
                                          PySide2.QtCore.QEvent.Type.UpdateLater
                                          PySide2.QtCore.QEvent.Type.Paint
                                          PySide2.QtCore.QEvent.Type.WindowDeactivate
                                          PySide2.QtCore.QEvent.Type.Hide
                                          

                                          closeEvent is never printed when I close the window. Shouldn't be somewhere after WindowDeactivate and before Hide?

                                          If I just open the software and close it without playing with the tabs, them the events are:

                                          PySide2.QtCore.QEvent.Type.PolishRequest
                                          PySide2.QtCore.QEvent.Type.Destroy
                                          

                                          I don't get why Destroy doesn't appears if I just switch to one tab to another (on the same MainWindow widget). Is the eventFilter bugged and it doesn't receives all the events?

                                          Z Offline
                                          Z Offline
                                          ZioLupo
                                          wrote on last edited by
                                          #20

                                          @Saelyth
                                          I think that we really have the same issue.
                                          AN issue that can be a wrong interpretation of how QtUiTools.QUiLoader().load works.
                                          It is returning an instance, not a class as.
                                          In this way we have two QMainWindow nested one in the other.
                                          With this workaround it worked:

                                              def __init__(self, ui_file, parent=None):
                                                  super(Form, self).__init__(parent)
                                                  self.ui=QtUiTools.QUiLoader().load(ui_file)
                                                  self.setCentralWidget(self.ui)
                                          

                                          But you loose the geometry of the QMainWindow designed with Designer (and maybe something more but I don't have the skill for investigating further)

                                          We should find a way to modify the inner closeEvent method but I don't know how to do it.
                                          Moreover I don't like to have two QMainWindow.

                                          Of course if someone has a real working sample code of a QMainWindow designed in Designer and then correctly loaded and used as a class... it would be really appreciated

                                          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