Catching QML window close
-
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.
-
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.
-
ixSci is right. You can learn more here http://doc.qt.nokia.com/4.7-snapshot/qml-component.html
-
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.
-
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]
-
I'm sorry for my late reply. I tried to debug the behavior and found out that following situations happen:
-
Eveything works OK: The Component.onDestraction signal is emitted, that invokes an onExit Python function, which kills a slave process and saves configuration.
-
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).
-
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.
-
-
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.
-
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.
-
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.