On Mon, 15 Mar 2010 15:40:14 +0300, z <[email protected]> wrote: > 2010/3/15 Phil Thompson <[email protected]> > >> On Mon, 15 Mar 2010 15:12:01 +0300, z <[email protected]> wrote: >> > 2010/3/15 Phil Thompson <[email protected]> >> > >> >> On Sun, 14 Mar 2010 22:06:02 +0300, z <[email protected]> wrote: >> >> > 2010/3/5 Phil Thompson <[email protected]> >> >> > >> >> >> On Fri, 5 Mar 2010 00:35:21 +0100, Kiwi <[email protected]> >> wrote: >> >> >> > Hi, >> >> >> > I'm totally new to PyQt programming. >> >> >> > While I was writing a very simple app for the system tray I think >> >> >> > I >> >> >> > found >> >> >> a >> >> >> > bug. >> >> >> > Here is a simple testcase: >> >> >> > >> >> >> > # -*- coding: utf-8 -*- >> >> >> > import sys >> >> >> > from PyQt4 import QtGui, QtCore >> >> >> > >> >> >> > app = QtGui.QApplication(sys.argv) >> >> >> > >> >> >> > tray = QtGui.QSystemTrayIcon() >> >> >> > >> >> >> > def a(): pass >> >> >> > def b(): pass >> >> >> > def c(): pass >> >> >> > def d(): pass >> >> >> > def e(): pass >> >> >> > def f(): pass >> >> >> > def g(): pass >> >> >> > def h(): pass >> >> >> > def i(): pass >> >> >> > def j(): pass >> >> >> > def k(): pass >> >> >> > >> >> >> > cm = QtGui.QMenu() >> >> >> > cm.addAction("Exit",QtGui.QApplication.quit) >> >> >> > >> >> >> > tray.setContextMenu(cm) >> >> >> > >> >> >> > tray.show() >> >> >> > sys.exit(app.exec_()) >> >> >> > >> >> >> > >> >> >> > note that the "defs" are needed to make the crash happen. >> >> >> > FYI, running linux on x86_64 >> >> >> > versions: >> >> >> > qt: 4.6.2 >> >> >> > pyqt: 4 4.7 >> >> >> > sip: 4.10 >> >> >> > python: 2.6.4 >> >> >> > gcc: 4.4.3 >> >> >> > libX11 1.3.3 >> >> >> > >> >> >> > here is the backtrace: >> >> >> > (gdb) run >> >> >> > Starting program: /usr/bin/python2.6 crash.py >> >> >> > [Thread debugging using libthread_db enabled] >> >> >> > QSystemTrayIcon::setVisible: No Icon set >> >> >> > >> >> >> > Program received signal SIGSEGV, Segmentation fault. >> >> >> > XFreeColormap (dpy=0x0, cmap=16777218) at FreeCmap.c:41 >> >> >> > 41 FreeCmap.c: No such file or directory. >> >> >> > in FreeCmap.c >> >> >> > (gdb) bt >> >> >> > #0 XFreeColormap (dpy=0x0, cmap=16777218) at FreeCmap.c:41 >> >> >> > #1 0x00007ffff5f1b558 in ~QSystemTrayIconSys (this=0x9c3070, >> >> >> > __in_chrg=<value optimized out>) at >> util/qsystemtrayicon_x11.cpp:213 >> >> >> > #2 0x00007ffff5f19ff4 in QSystemTrayIconPrivate::remove_sys >> >> >> > (this=0x9bc310) at util/qsystemtrayicon_x11.cpp:352 >> >> >> > #3 0x00007ffff5f0637f in ~QSystemTrayIcon (this=0x8c6590, >> >> >> > __in_chrg=<value optimized out>) at util/qsystemtrayicon.cpp:152 >> >> >> > #4 0x00007ffff65f46f2 in ~sipQSystemTrayIcon (this=0x8c6590, >> >> >> > __in_chrg=<value optimized out>) at >> >> >> > sipQtGuiQSystemTrayIcon.cpp:137 >> >> >> > #5 0x00007ffff65f347c in release_QSystemTrayIcon >> (sipCppV=0x8c6590, >> >> >> > sipState=<value optimized out>) at >> >> >> > sipQtGuiQSystemTrayIcon.cpp:752 >> >> >> > #6 0x00007ffff219c289 in sipWrapper_dealloc (self=0x0) at >> >> >> > siplib.c:9675 >> >> >> > #7 0x00007ffff7adc0e5 in subtype_dealloc (self=0x7ffff7f1caf0) >> >> >> > at >> >> >> > Objects/typeobject.c:1019 >> >> >> > #8 0x00007ffff7aba0cf in insertdict (mp=0x63cf60, >> >> >> > key=0x7ffff7f08870, >> >> >> > hash=2314047222216391292, value=0x7ffff7dab5d0) at >> >> >> > Objects/dictobject.c:459 >> >> >> > #9 0x00007ffff7abcb15 in PyDict_SetItem (op=0x63cf60, >> >> >> > key=0x7ffff7f08870, value=0x7ffff7dab5d0) at >> >> >> > Objects/dictobject.c:701 >> >> >> > #10 0x00007ffff7abe48d in _PyModule_Clear (m=<value optimized >> >> >> > out>) >> >> >> > at >> >> >> > Objects/moduleobject.c:138 >> >> >> > #11 0x00007ffff7b2ac4f in PyImport_Cleanup () at >> Python/import.c:439 >> >> >> > #12 0x00007ffff7b33c46 in Py_Finalize () at >> >> >> > Python/pythonrun.c:434 >> >> >> > #13 0x00007ffff7b33d58 in Py_Exit (sts=0) at >> Python/pythonrun.c:1714 >> >> >> > #14 0x00007ffff7b33e87 in handle_system_exit () at >> >> >> Python/pythonrun.c:1116 >> >> >> > #15 0x00007ffff7b340cd in PyErr_PrintEx (set_sys_last_vars=1) at >> >> >> > Python/pythonrun.c:1126 >> >> >> > #16 0x00007ffff7b345a6 in PyRun_SimpleFileExFlags >> >> >> > (fp=0x7fffffffe578, >> >> >> > filename=0x7fffffffe578 "crash.py", closeit=1, >> flags=0x7fffffffe0d0) >> >> >> > at Python/pythonrun.c:935 >> >> >> > #17 0x00007ffff7b40721 in Py_Main (argc=-134926176, argv=<value >> >> >> > optimized out>) at Modules/main.c:599 >> >> >> > #18 0x00007ffff74ebbbd in __libc_start_main (main=<value >> >> >> > optimized >> >> >> > out>, argc=<value optimized out>, ubp_av=<value optimized out>, >> >> >> > init=<value optimized out>, >> >> >> > fini=<value optimized out>, rtld_fini=<value optimized out>, >> >> >> > stack_end=0x7fffffffe1e8) at libc-start.c:220 >> >> >> > #19 0x00000000004006b >> >> >> > (gdb) f 6 >> >> >> > #6 0x00007ffff219c289 in sipWrapper_dealloc (self=0x0) at >> >> >> > siplib.c:9675 >> >> >> > 9675 forgetObject((sipSimpleWrapper *)self); >> >> >> > (gdb) f 5 >> >> >> > #5 0x00007ffff65f347c in release_QSystemTrayIcon >> (sipCppV=0x8c6590, >> >> >> > sipState=<value optimized out>) at >> >> >> > sipQtGuiQSystemTrayIcon.cpp:752 >> >> >> > warning: Source file is more recent than executable. >> >> >> > 752 delete reinterpret_cast<QSystemTrayIcon >> *>(sipCppV); >> >> >> > Current language: auto >> >> >> > The current source language is "auto; currently c++". >> >> >> > (gdb) f 4 >> >> >> > #4 0x00007ffff65f46f2 in ~sipQSystemTrayIcon (this=0x8c6590, >> >> >> > __in_chrg=<value optimized out>) at >> >> >> > sipQtGuiQSystemTrayIcon.cpp:137 >> >> >> > 137 } >> >> >> >> >> >> Crashes on exit like this are caused by Qt objects being deleted in >> >> >> the >> >> >> "wrong" order. Unfortunately PyQt has (almost) no control over that >> >> >> order. >> >> >> By adding those dummy functions you are altering the order in which >> >> >> things >> >> >> get garbage collected. It doesn't happen with C++ applications >> because >> >> >> the >> >> >> objects don't get deleted. >> >> >> >> >> >> >> >> > I found another problem, which i think is also caused by delete >> >> > order: >> >> > ###### >> >> > app = QApplication(sys.argv) >> >> > >> >> > pushButton = QPushButton() >> >> > gProxyButton = QGraphicsProxyWidget() >> >> > gProxyButton.setWidget(pushButton) >> >> > >> >> > view = QGraphicsView() >> >> > view.show() >> >> > >> >> > app.exec_() >> >> > sys.exit() >> >> > ###### >> >> > on exit this program will crash with segfault. >> >> > but if the proxy widget will be added to the scene, or explicitly >> >> > deleted >> >> > afer app.exec_(), all will be fine >> >> >> >> So why would you not add it to a QGraphicsScene? >> >> >> > >> > In my program, i have several items, which will be added to the scene >> > and >> > showed only after some event (button click, for ex.). They are >> > collecting >> > data, while not being shown, and therefore should persist during all >> > application lifetime. But the user might exit application, and do not >> > necessarily trigger their showing action. And application crashes. >> >> Wouldn't it be better to always add the widget to the scene, let Qt >> create >> the proxy for you, and just hide it until it is needed? >> > Yes, in my usecase it is possible to overcome problem this way. But > requiring an item to be in the scene is a bit strict. Putting such a > restriction on top of Qt is tricky to find out and debug what's happening. > If it can be solved by PyQt itself, the same way as the problem with > QSysremTrayIcon - it would save some blood of developers. (And PySide just > works ;)
The general problem can happen with any sort of object. It only makes sense to give special treatment to objects involved in common or preferred use cases. Phil _______________________________________________ PyQt mailing list [email protected] http://www.riverbankcomputing.com/mailman/listinfo/pyqt
