[PyQt] causes self to be owned by Qt instead of PyQt ???
Florian Bruhin
me at the-compiler.org
Wed Apr 1 08:03:20 BST 2015
Hi,
(note: I'm not 100% sure about my answers - so if I'm wrong somewhere,
someone please correct me!)
* redstone-cold <redstone-cold at 163.com> [2015-04-01 14:32:19 +0800]:
> How do you know the crash happens in QObject::thread()?
(I got this off-list, but I'm answering here as well)
There are two approaches to get more info (i.e. a C++ stacktrace) when
debugging segfaults:
- Prepending the commandline with 'catchsegv'. This is very easy, but
will print mangled C++ symbols like _ZNK7QObject6threadEv which you
need to decode via c++filt or http://demangler.com/
- Running it inside gdb, usually with something like:
gdb /usr/bin/python3.4 -ex run
And then using 'bt' to get a backtrace when the segfault happens.
> sip.setdestroyonexit(False) is the default with PyQt5 ?How do you
> know this ?
I don't know where I originally picked it up, but it's listed here:
http://pyqt.sourceforge.net/Docs/PyQt5/pyqt4_differences.html#object-destruction-on-exit
> 1)"The parent argument, if not None, causes self to be owned by Qt instead of PyQt", does owned by PyQt also mean the object owned by Python ?
> If it is true ,then another question below
Yes - something is either owned by Python/PyQt, or by C++/Qt.
> 2)In the doc of sip.setdestroyonexit(destroy) says, "Calling this function with a value of False disables the automatic destruction of C++ instances and C structures(owned by Python)." ,then which is responsible for destroying these C++ instances and C structures? the dtor of them ?
The destructors will never be called in that case - which *usually*
isn't an issue, because the application is exiting anyways.
> 3)In the doc of sip.setdestroyonexit(destroy) says,"When the Python interpreter exits it garbage collects those objects that it can. This means that any corresponding C++ instances and C structures owned by Python are destroyed. Unfortunately this happens in an unpredictable order and so can cause memory faults within the wrapped library. "
>
>
> "since Python does not guarantee that objects will be deleted in a specific order when it exits. On the other hand, when Qt deletes an object, it always tries to delete all its children as well, which will normally ensure that objects get deleted in the right order. This is especially important when Qt takes ownership of an object, because you could end up in a situation where an attempt is made to delete the object twice (which will result in a crash)." quoted from here http://stackoverflow.com/questions/27131294/error-qobjectstarttimer-qtimer-can-only-be-used-with-threads-started-with-qt
>
>
> Since Qt ensure that objects get deleted in the right order, so is it better to let the parent argument not be None, thus causes self to be owned by Qt instead of PyQt? or just set sip.setdestroyonexit(False) ?
I think it's always a good idea to supply a parent to QObjects, except
in one of these cases:
- It's a top level window.
- You know it'll be reparented by Qt, e.g. a widget which will be
added to a layout.
> 4) When I Wrapped the if __name__ == '__main__': part in a function main(),the issue went away ,can you explain why ? changed version https://bpaste.net/show/36c594a1c82e
That's interesting - the link above (PyQt4/PyQt5 differences)
recommends not doing that. But that's the tricky thing about such
segfaults - they don't always happen, and when you touch *something*
they maybe go away.
Florian
--
http://www.the-compiler.org | me at the-compiler.org (Mail/XMPP)
GPG: 916E B0C8 FD55 A072 | http://the-compiler.org/pubkey.asc
I love long mails! | http://email.is-not-s.ms/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20150401/d20b5755/attachment.sig>
More information about the PyQt
mailing list