[PyQt] Conflict between setuptools & requirements in official PyQt5 docs

Elvis Stansvik elvstone at gmail.com
Tue Feb 9 16:04:18 GMT 2016


2016-02-09 12:21 GMT+01:00 Kovid Goyal <kovid at kovidgoyal.net>:
>> Have you been able to pinpoint when and why crashes happen despite
>> setdestroyonexit() (default in PyQt5)? I've not had any crashes on
>> exit myself yet. Could it be that you have orphan QObjects? (thought
>> that would only mean they simple don't get destroyed I guess?).
>
> Yes, I have described my findings in the past. Just search
> this list's archives for mails by me. The crashes on exit can be easily
> replicated with a five line script on linux, that uses the qwebengine
> modules. As for root causes, I haven't looked very deeply into it, but,
> my guess is that when there is a reference cycle, the python garbage
> collector has to break it, and the order in which it breaks it is
> random. Therefore the order in which the destructors are called is
> random, instead of the order that would be expected by Qt's parent child
> relationship.
>
> A possible PyQt level workaround would be to have a global flag that is set on
> application shutdown that disables the calling of all C++ destructors,
> similar to destroyonexit() but more general. I haven't looked into
> whether such a flag would be feasible or not -- unfortunately, I have
> too many other demands on my time, and since I can workaround the
> problem in my own code, the need has not been pressing for me.

Alright, thanks for the info.

I actually just (for the first time) ran into a problem which was
possibly due to undefined destruction order at exit:

QBasicTimer::start: QBasicTimer can only be used with threads started
with QThread
QBasicTimer::start: QBasicTimer can only be used with threads started
with QThread
QBasicTimer::start: QBasicTimer can only be used with threads started
with QThread

And your solution with keeping a module level reference to the app
instance worked great. Thanks for that!

Elvis

>
> Kovid.
>
>>
>> Elvis
>>
>> >
>> > Kovid.
>> >
>> > On Mon, Feb 08, 2016 at 05:43:36PM +0000, Phil Thompson wrote:
>> >> On 8 Feb 2016, at 5:01 pm, Damon Lynch <damonlynch at gmail.com> wrote:
>> >> >
>> >> > The PyQt5 docs explicitly say not to put the application startup logic in a function e.g. main():
>> >> >
>> >> > http://pyqt.sourceforge.net/Docs/PyQt5/pyqt4_differences.html#object-destruction-on-exit
>> >> >
>> >> > Whereas setuptools and its entry_points feature requires the startup logic be in a function.
>> >> >
>> >> > From looking through a bunch of projects on github, I see that the great majority simply ignore the official PyQt5 advice, and have a main() type function with all their startup logic.
>> >> >
>> >> > However at least one project takes the approach of deleting PyQt objects before exit (drawing on an insight offered by Dr. Koval):
>> >> >
>> >> > def main():
>> >> >     import sys
>> >> >     app = QtGui.QApplication(sys.argv)
>> >> >     window = DataViz()
>> >> >     window.show()
>> >> >     app.exec_()
>> >> >     # fixed segfaults at exit:
>> >> >     # http://python.6.x6.nabble.com/Application-crash-on-exit-under-Linux-td5067510.html
>> >> >     del window
>> >> >     del app
>> >> >     sys.exit(0)
>> >> >
>> >> > if __name__ == '__main__':
>> >> >     main()
>> >> >
>> >> >
>> >> > Source: https://github.com/subhacom/dataviz/blob/e62a591149750e5e5d21f13b4dfee28409a3d683/dataviz/dataviz.py
>> >> >
>> >> > Is this approach guaranteed to work as well as the approach specified in the official docs?
>> >>
>> >> That's PyQt4 code.
>> >>
>> >> The advice is contradictory - but it has to be. pyqtdeploy uses setuptools and has a main() entry point. For most of the time it's not a problem - so you are unlucky to hit it, rather than being lucky not to. However the worse aspect of it is that is can occur apparently randomly (ie. it can be very difficult to identify what change to the application triggered it).
>> >>
>> >> I've toned down the section in the docs so that it says "try to avoid" rather than "don't".
>> >>
>> >> The other bit of advice is to try and make sure there are only two global QObjects in your application - the QApplication and the top-level GUI widget. Try and make sure that every other QObject has an appropriate parent. That way Qt should destroy things in a safe order.
>> >>
>> >> Phil
>> >> _______________________________________________
>> >> PyQt mailing list    PyQt at riverbankcomputing.com
>> >> https://www.riverbankcomputing.com/mailman/listinfo/pyqt
>> >
>> > --
>> > _____________________________________
>> >
>> > Dr. Kovid Goyal
>> > http://www.kovidgoyal.net
>> > http://calibre-ebook.com
>> > _____________________________________
>> > _______________________________________________
>> > PyQt mailing list    PyQt at riverbankcomputing.com
>> > https://www.riverbankcomputing.com/mailman/listinfo/pyqt
>>
>
> --
> _____________________________________
>
> Dr. Kovid Goyal
> http://www.kovidgoyal.net
> http://calibre-ebook.com
> _____________________________________


More information about the PyQt mailing list