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.
  • 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
                              • SGaistS Offline
                                SGaistS Offline
                                SGaist
                                Lifetime Qt Champion
                                wrote on last edited by
                                #21

                                Then remove your Form class as it's not useful in your case.

                                You can then create a custom event filter object that should handle the close event and whatever you want to do in 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
                                • SaelythS Offline
                                  SaelythS Offline
                                  Saelyth
                                  wrote on last edited by Saelyth
                                  #22

                                  With the original @ZioLupo code the override of eventFilter would works just fine, but closeEvent wouldn't (that was the issue).

                                  class Form(QtWidgets.QMainWindow):
                                      def __init__(self):
                                          super().__init__()
                                          self.ui = QUiLoader().load("myfile.ui")
                                          self.ui.buttonLoad.clicked.connect(self.load_something)
                                  
                                      def eventFilter(self, target, event):
                                          print("this works")
                                          return False
                                  
                                      def closeEvent(self, event):
                                          print("this doesn't works")
                                  

                                  But that creates two QWidgets (one for the Form class and one for self.ui). if I understood you right, @Sgaist, you suggest to make the Form class a non-QWidget, as the Qwidget will be load into self.ui, right? But then, if the Form class is not a QWidget, I don't get how to set the closeEvent or eventFilter methods for the self.ui QWidget.

                                  I tried to do what you suggest with my next code. The windows open just fine but no override works and no events get to my handlers.

                                  class Form(object):
                                      def __init__(self):
                                          super().__init__()
                                          self.ui = QUiLoader().load("myfile.ui")
                                          self.ui.eventFilter = self.eventFilter
                                          self.ui.closeEvent = self.closeEvent
                                  
                                      def eventFilter(self, target, event):
                                          print("doesn't works")
                                          return False
                                  
                                      def closeEvent(self, event):
                                          print("doesn't works")
                                  

                                  I think the issue here is that we were waiting for PySide2 while we were working temporary on PyQt5, and assumed that PySide2 would behave like PyQt5, where we would port our Qt Designer UI to .py with pyuic command. But when PySide2 was released, we saw an alternative way to do things (load the .ui file directly) and now we are trying to skip one of the step (it seems unnecesary to convert the .ui file to .py in PySide2 if we can directly load the .ui file). However, while trying to do that, we got lost in the process as we lost something which we were familiar with: the abbility to override the UI events.

                                  A working example on how to load a .ui file with PySide2 where closeEvent works would help us a lot.

                                  JonBJ 1 Reply Last reply
                                  0
                                  • Z ZioLupo

                                    @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 Offline
                                    ewerybodyE Offline
                                    ewerybody
                                    wrote on last edited by
                                    #23

                                    @ZioLupo said in closeEvent not working:

                                    @ewerybody
                                    As I wrote some message after, yes there is -of course - pyside2-uic!

                                    Sorry. I didn't see you writing this.
                                    What I just meant is that the name is NOT pyside2-uic (with a dash) but pyside2uic without the dash!

                                    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

                                    I would always avoid loading ui files directly and compile them only when changed. This way you can easily debug/step through the code. You see the generated structure and you can learn how UIs are written and you can strip a release of the ui files in the end.

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

                                      Just one thing: you are not using eventFilter correctly, you don't install 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
                                      • SaelythS Saelyth

                                        With the original @ZioLupo code the override of eventFilter would works just fine, but closeEvent wouldn't (that was the issue).

                                        class Form(QtWidgets.QMainWindow):
                                            def __init__(self):
                                                super().__init__()
                                                self.ui = QUiLoader().load("myfile.ui")
                                                self.ui.buttonLoad.clicked.connect(self.load_something)
                                        
                                            def eventFilter(self, target, event):
                                                print("this works")
                                                return False
                                        
                                            def closeEvent(self, event):
                                                print("this doesn't works")
                                        

                                        But that creates two QWidgets (one for the Form class and one for self.ui). if I understood you right, @Sgaist, you suggest to make the Form class a non-QWidget, as the Qwidget will be load into self.ui, right? But then, if the Form class is not a QWidget, I don't get how to set the closeEvent or eventFilter methods for the self.ui QWidget.

                                        I tried to do what you suggest with my next code. The windows open just fine but no override works and no events get to my handlers.

                                        class Form(object):
                                            def __init__(self):
                                                super().__init__()
                                                self.ui = QUiLoader().load("myfile.ui")
                                                self.ui.eventFilter = self.eventFilter
                                                self.ui.closeEvent = self.closeEvent
                                        
                                            def eventFilter(self, target, event):
                                                print("doesn't works")
                                                return False
                                        
                                            def closeEvent(self, event):
                                                print("doesn't works")
                                        

                                        I think the issue here is that we were waiting for PySide2 while we were working temporary on PyQt5, and assumed that PySide2 would behave like PyQt5, where we would port our Qt Designer UI to .py with pyuic command. But when PySide2 was released, we saw an alternative way to do things (load the .ui file directly) and now we are trying to skip one of the step (it seems unnecesary to convert the .ui file to .py in PySide2 if we can directly load the .ui file). However, while trying to do that, we got lost in the process as we lost something which we were familiar with: the abbility to override the UI events.

                                        A working example on how to load a .ui file with PySide2 where closeEvent works would help us a lot.

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

                                        @Saelyth
                                        As per what @SGaist has written, in my PyQt like yours (my page class is derived from QWidget) the __init__() ends with line:

                                            self.window().installEventFilter(self)
                                        

                                        and my event handlers (eventFilter()) work.

                                        SaelythS 1 Reply Last reply
                                        0
                                        • JonBJ JonB

                                          @Saelyth
                                          As per what @SGaist has written, in my PyQt like yours (my page class is derived from QWidget) the __init__() ends with line:

                                              self.window().installEventFilter(self)
                                          

                                          and my event handlers (eventFilter()) work.

                                          SaelythS Offline
                                          SaelythS Offline
                                          Saelyth
                                          wrote on last edited by Saelyth
                                          #26

                                          @JonB On PyQt and PyQt5 it works (I've been using it that way) but on Pyside2 it doesn't. Note that I was installing the filters (I just forgot to type it in my previous message). Anyway I ended up using pyside2-uic (with a dash) to make my code safer to this issues.

                                          1 Reply Last reply
                                          1

                                          • Login

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