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