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

Reply via email to