Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Catching QML window close
QtWS25 Last Chance

Catching QML window close

Scheduled Pinned Locked Moved QML and Qt Quick
14 Posts 5 Posters 20.9k 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.
  • J Offline
    J Offline
    jech
    wrote on last edited by
    #1

    I need to call a function when the QML application closes. I use Python (PySide) as the application backend. But I suppose it should be the same for C++.

    So how do I find out that the application closes and call a function?

    1 Reply Last reply
    0
    • A Offline
      A Offline
      anselmolsm
      wrote on last edited by
      #2

      Hi!,
      Check if "QCloseEvent":http://doc.qt.nokia.com/4.7/qcloseevent.html or the QWidget's "closeEvent":http://doc.qt.nokia.com/4.7/qwidget.html#closeEvent can help you.

      EDIT: supposing you're using a wrapper to run your QML code.

      Anselmo L. S. Melo (anselmolsm)

      1 Reply Last reply
      0
      • J Offline
        J Offline
        jech
        wrote on last edited by
        #3

        It wasn't exactly the solution, but by reading it's documentation I discovered a "destroyed()" signal, which is emitted by rootContext when I close the window.

        1 Reply Last reply
        0
        • J Offline
          J Offline
          jech
          wrote on last edited by
          #4

          Unfortunately after some time, I noticed that this solution is very unreliable. Sometimes the signal is called but sometimes it isn't. This causes that configuration is not saved and slave processes remain running, which is a very bad behavior.

          Do you have any idea how can be reliably called a function at program close? The closeEvent is a good solution for traditional PySide programs, but I don't see how could I use it with a QML UI.

          1 Reply Last reply
          0
          • I Offline
            I Offline
            ixSci
            wrote on last edited by
            #5

            Maybe you should try *Component.onDestraction * at the main "window" of your application? It seems appropriate for your goal.

            1 Reply Last reply
            0
            • M Offline
              M Offline
              mohsen
              wrote on last edited by
              #6

              ixSci is right. You can learn more here http://doc.qt.nokia.com/4.7-snapshot/qml-component.html

              1 Reply Last reply
              0
              • J Offline
                J Offline
                jech
                wrote on last edited by
                #7

                Unfortunately it also doesn't work reliably. Sometimes the connected Python function is not called.

                1 Reply Last reply
                0
                • I Offline
                  I Offline
                  ixSci
                  wrote on last edited by
                  #8

                  I think there is no more reliable solution. What is the problem you have? Maybe you can make up some simple example of your troubles and we will try to eliminate them?

                  1 Reply Last reply
                  0
                  • B Offline
                    B Offline
                    blam
                    wrote on last edited by
                    #9

                    If the QML application is loaded by a QDeclarativeView, then you could subclass QDeclarativeView and implement the closeEvent() as previously suggested.

                    With regards to Component.onDestruction, the component would only be destroyed until the QDeclarativeView is deleted (and not just closed). If the view should be deleted when it is closed then you could set its Qt::WA_DeleteOnClose attribute.

                    1 Reply Last reply
                    0
                    • M Offline
                      M Offline
                      mohsen
                      wrote on last edited by
                      #10

                      It's the second solution.

                      [quote author="blam" date="1294275363"]If the QML application is loaded by a QDeclarativeView, then you could subclass QDeclarativeView and implement the closeEvent() as previously suggested.

                      With regards to Component.onDestruction, the component would only be destroyed until the QDeclarativeView is deleted (and not just closed). If the view should be deleted when it is closed then you could set its Qt::WA_DeleteOnClose attribute.[/quote]

                      1 Reply Last reply
                      0
                      • J Offline
                        J Offline
                        jech
                        wrote on last edited by
                        #11

                        I'm sorry for my late reply. I tried to debug the behavior and found out that following situations happen:

                        1. Eveything works OK: The Component.onDestraction signal is emitted, that invokes an onExit Python function, which kills a slave process and saves configuration.

                        2. PySide fails: The Component.onDestraction signal is emitted, onExit function is executed, but the slave process isn't killed and Python refuses to quit (complains about other threads still running).

                        3. PySide fails: The Component.onDestraction signal is emitted, but the onExit function isn't executed. After this Python either exits without an error or crashes.

                        The behavior is quite random, it behaves differently on different machines. I'm afraid it's a PySide problem (or my incorrect code), but since it happens randomly, I have no idea how could I provide a simple example.

                        I use some timers and a slave process running in a separate thread. Do I have to kill the threads manually on exit? I thought it should happen automatically.

                        1 Reply Last reply
                        0
                        • B Offline
                          B Offline
                          blam
                          wrote on last edited by
                          #12

                          Is your QML running in another thread? If so that wouldn't be a good idea; it has to be run in the main thread.

                          Otherwise, it could be that the Component.onDestruction signal is not what you need; perhaps you want to use the destroyed() signal from the QDeclarativeView (and setting Qt::WA_DeleteOnClose) or its engine.

                          1 Reply Last reply
                          0
                          • J Offline
                            J Offline
                            jech
                            wrote on last edited by
                            #13

                            The QML is running from the main thread. I will also test my application on Linux and with PySide 1.0 beta3, which was just released. If the problems remain, I'll will analyze it more deeply and will try to find out what causes the crash.

                            Edit: One of the errors I'm getting is this: file:///../PyPlay.qml:23: TypeError: Result of expression 'controller' [undefined] is not an object. The controller object is used for calling functions (slots) in PySide. At lines 21-24 there is this code:
                            @ Component.onDestruction: {
                            console.log("QML exit")
                            controller.onExit()
                            }
                            @

                            So the problem appears when calling the onExit Python function. The first command of this function to write a debug information to console. It's not written, so calling of the function fails completely. It seems to me that the Python part is destroyed to early. Subclassing the QDeclarativeView might be the solution my idea is right.

                            1 Reply Last reply
                            0
                            • J Offline
                              J Offline
                              jech
                              wrote on last edited by
                              #14

                              I just tried PySide 1.0 beta 3 but it behaves exactly as beta 1. So sometimes it crashes Python when i quit the application.

                              So I subclassed QDeclarativeView and defined a closeEvent function. This seems to be working so far.

                              The difference between the two approaches is that with closeEvent the application window isn't closed before the function finishes. But with the use of different signals, the window closed but other Python threads were still running, which probably caused the crashes I was experiencing.

                              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