Re: [PyQt] removeWidget
Le 25/08/11 07:59, uahmed a crit: Hi I want to add widget in (f1) function and want to remove the widget from (f2) function . I tried the same thing in same function it do work but when i try to remove the widget from another it doesnt . Any help ? Code : import sys,os from functools import partial from PyQt4 import QtGui, QtCore import Skype4Py import time import socket class main(): def f1(self): print "f1" buttons['user'] = QtGui.QToolButton(widget) layout.addWidget(buttons['user']) widget.setLayout(layout) def f2(self): print "f2" layout.removeWidget(buttons['user']) widget.setLayout(layout) app = QtGui.QApplication(sys.argv) widget = QtGui.QWidget() layout = QtGui.QVBoxLayout() buttons = {} sk = main() sk.f1() sk.f2() widget.show() sys.exit(app.exec_()) ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt Remove is NOT delete. Try that: def f2(self): print "f2" buttons['user'].deleteLater() layout.removeWidget(buttons['user']) widget.setLayout(layout) -- Vincent V.V. Oqapy . Qarte+7 . PaQager ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] removeWidget
On Thursday 25 August 2011, 10:43:20 Vincent Vande Vyvre wrote: Le 25/08/11 07:59, uahmed a écrit : Hi I want to add widget in (f1) function and want to remove the widget from (f2) function . I tried the same thing in same function it do work but when i try to remove the widget from another it doesnt . Any help ? Code : import sys,os from functools import partial from PyQt4 import QtGui, QtCore import Skype4Py import time import socket class main(): def f1(self): print f1 buttons['user'] = QtGui.QToolButton(widget) layout.addWidget(buttons['user']) widget.setLayout(layout) def f2(self): print f2 layout.removeWidget(buttons['user']) widget.setLayout(layout) app = QtGui.QApplication(sys.argv) widget = QtGui.QWidget() layout = QtGui.QVBoxLayout() buttons = {} sk = main() sk.f1() sk.f2() widget.show() sys.exit(app.exec_()) ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt Remove is NOT delete. Try that: def f2(self): print f2 buttons['user'].deleteLater() layout.removeWidget(buttons['user']) widget.setLayout(layout) Consider using .show() and .hide() Pete ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] removeWidget
Hi Thanks for the reply , I used .close() . I guess this will destroy the widget and will not leave memory for it . On Thu, Aug 25, 2011 at 2:22 PM, Hans-Peter Jansen h...@urpla.net wrote: On Thursday 25 August 2011, 10:43:20 Vincent Vande Vyvre wrote: Le 25/08/11 07:59, uahmed a écrit : Hi I want to add widget in (f1) function and want to remove the widget from (f2) function . I tried the same thing in same function it do work but when i try to remove the widget from another it doesnt . Any help ? Code : import sys,os from functools import partial from PyQt4 import QtGui, QtCore import Skype4Py import time import socket class main(): def f1(self): print f1 buttons['user'] = QtGui.QToolButton(widget) layout.addWidget(buttons['user']) widget.setLayout(layout) def f2(self): print f2 layout.removeWidget(buttons['user']) widget.setLayout(layout) app = QtGui.QApplication(sys.argv) widget = QtGui.QWidget() layout = QtGui.QVBoxLayout() buttons = {} sk = main() sk.f1() sk.f2() widget.show() sys.exit(app.exec_()) ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt Remove is NOT delete. Try that: def f2(self): print f2 buttons['user'].deleteLater() layout.removeWidget(buttons['user']) widget.setLayout(layout) Consider using .show() and .hide() Pete ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] removeWidget
[I prefer to not get personal replies on this list] On Thursday 25 August 2011, 11:39:46 uahmed wrote: Hi Thanks for the reply , I used .close() . I guess this will destroy the widget and will not leave memory for it . You cannot close arbitrary widgets, but you can hide and show them without the need to fiddle with the layouts.. Pete ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Updating Qlabel in widget
Hi I want to update the Qlabel after the widget is made , Problem is that updating is base on counter so i call that function after 4 seconds , but when it by pass the if statment it go through all the commands give me no errors but it does not update the widet although if i dont putt if statment all lines are executed and Qlabel update too . Can you please tell me where i am wrong Here is code import sys,os from functools import partial from PyQt4 import QtGui, QtCore import time class main(): def f2(self): print f2 global count count +=1 if ( count == 2): msg_label[user] = QtGui.QLabel(update,widget) msg_label[user].setGeometry(10, 10, 100, 100) print count QtCore.QTimer.singleShot(4000, self.f2) app = QtGui.QApplication(sys.argv) widget = QtGui.QWidget() layout = QtGui.QVBoxLayout() buttons = {} count = 0 msg_label = {} sk = main() sk.f2() widget.show() sys.exit(app.exec_()) ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] removeWidget
Hi [Sorry Hans , i clicked on reply all so it Cc to the group too ] Although here i want to destroy the button like i dont want to use it again , if i am not wrong show and hide functions will be use when i want to reuse the button and show and hide will not destroy the button . On Thu, Aug 25, 2011 at 2:58 PM, Hans-Peter Jansen h...@urpla.net wrote: [I prefer to not get personal replies on this list] On Thursday 25 August 2011, 11:39:46 uahmed wrote: Hi Thanks for the reply , I used .close() . I guess this will destroy the widget and will not leave memory for it . You cannot close arbitrary widgets, but you can hide and show them without the need to fiddle with the layouts.. Pete ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Updating Qlabel in widget
On Thursday 25 August 2011, 12:02:52 uahmed wrote: Hi I want to update the Qlabel after the widget is made , Problem is that updating is base on counter so i call that function after 4 seconds , but when it by pass the if statment it go through all the commands give me no errors but it does not update the widet although if i dont putt if statment all lines are executed and Qlabel update too . Can you please tell me where i am wrong Here is code import sys,os from functools import partial from PyQt4 import QtGui, QtCore import time class main(): def f2(self): print f2 global count count +=1 if ( count == 2): msg_label[user] = QtGui.QLabel(update,widget) msg_label[user].setGeometry(10, 10, 100, 100) print count QtCore.QTimer.singleShot(4000, self.f2) app = QtGui.QApplication(sys.argv) widget = QtGui.QWidget() layout = QtGui.QVBoxLayout() buttons = {} count = 0 msg_label = {} sk = main() sk.f2() widget.show() sys.exit(app.exec_()) Don't recreate the widget over and over again. Create it once, and just change the label with setText(). Pete ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Updating Qlabel in widget
hi Thanks for the reply , QLabel will be created once only when count is equal to 2 . Firstly i was thinking same that i make Qlabel first and then recall them and change only text but if i do that then i have to create nearly 40-60 Qlabel to cover all the loop holes so i need to create it on run time to avoid making lots of Qlabels On Thu, Aug 25, 2011 at 3:26 PM, Hans-Peter Jansen h...@urpla.net wrote: On Thursday 25 August 2011, 12:02:52 uahmed wrote: Hi I want to update the Qlabel after the widget is made , Problem is that updating is base on counter so i call that function after 4 seconds , but when it by pass the if statment it go through all the commands give me no errors but it does not update the widet although if i dont putt if statment all lines are executed and Qlabel update too . Can you please tell me where i am wrong Here is code import sys,os from functools import partial from PyQt4 import QtGui, QtCore import time class main(): def f2(self): print f2 global count count +=1 if ( count == 2): msg_label[user] = QtGui.QLabel(update,widget) msg_label[user].setGeometry(10, 10, 100, 100) print count QtCore.QTimer.singleShot(4000, self.f2) app = QtGui.QApplication(sys.argv) widget = QtGui.QWidget() layout = QtGui.QVBoxLayout() buttons = {} count = 0 msg_label = {} sk = main() sk.f2() widget.show() sys.exit(app.exec_()) Don't recreate the widget over and over again. Create it once, and just change the label with setText(). Pete ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] segfault when using Qt.QueuedConnection
Hi, After lots of tries I have been able to get a stacktrace + core of a segfault that I believe occurs from time to time. The attached stacktrace shows the segfault is inside the QT event loop, without even involving Python. What I believe that happens is this : 1) A signal is connected to a slot with a queued connection. 2) within PyQtProxy::unislot, the sender() mehtod is called on a QObject 3) the documentation of sender() however states that the returned pointer is only valid if the sending object has not been deleted yet. I think the segfault occurs because sometimes this object has been deleted allready, and thus the casting of the sender object to its type segfaults the application sometimes. Best regards and thanks for any view on this. Erik #0 0x in ?? () #1 0x01066baf in QMetaObject::cast (this=0xe22c04, obj=0x9ba5ce8) at kernel/qmetaobject.cpp:266 #2 0x00d929b1 in qobject_castPyQtShortcircuitSignalProxy* (object=0x9ba5ce8) at ../../../install/include/QtCore/qobject.h:366 #3 0x00d91e70 in PyQtProxy::unislot (this=0xa4d5718, qargs=0xb565fb60) at qpycore_pyqtproxy.cpp:406 #4 0x00d91e08 in PyQtProxy::qt_metacall (this=0xa4d5718, _c=QMetaObject::InvokeMetaMethod, _id=1, _a=0xb565fb60) at qpycore_pyqtproxy.cpp:380 #5 0x01066b92 in QMetaObject::metacall (object=0xa4d5718, cl=QMetaObject::InvokeMetaMethod, idx=5, argv=0xb565fb60) at kernel/qmetaobject.cpp:237 #6 0x0107596b in QMetaCallEvent::placeMetaCall (this=0xb565fd30, object=0xa4d5718) at kernel/qobject.cpp:535 #7 0x010773e3 in QObject::event (this=0xa4d5718, e=0xb565fd30) at kernel/qobject.cpp:1217 #8 0x0135c27a in QApplicationPrivate::notify_helper (this=0x8a13790, receiver=0xa4d5718, e=0xb565fd30) at kernel/qapplication.cpp:4462 #9 0x01359c40 in QApplication::notify (this=0x86c5760, receiver=0xa4d5718, e=0xb565fd30) at kernel/qapplication.cpp:3862 #10 0x07735f02 in sipQApplication::notify (this=0x86c5760, a0=0xa4d5718, a1=0xb565fd30) at sipQtGuiQApplication.cpp:317 #11 0x0105f178 in QCoreApplication::notifyInternal (this=0x86c5760, receiver=0xa4d5718, event=0xb565fd30) at kernel/qcoreapplication.cpp:731 #12 0x00d3079f in QCoreApplication::sendEvent (receiver=0xa4d5718, event=0xb565fd30) at /home/tw55413/workspaces/cpd/trunk/linux2-debug/install/include/QtCore/qcoreapplication.h:215 #13 0x0106018c in QCoreApplicationPrivate::sendPostedEvents (receiver=0x0, event_type=0, data=0x8940ce0) at kernel/qcoreapplication.cpp:1372 #14 0x0105fe83 in QCoreApplication::sendPostedEvents (receiver=0x0, event_type=0) at kernel/qcoreapplication.cpp:1265 #15 0x00d307d2 in QCoreApplication::sendPostedEvents () at /home/tw55413/workspaces/cpd/trunk/linux2-debug/install/include/QtCore/qcoreapplication.h:220 #16 0x01096958 in postEventSourceDispatch (s=0x8a15388) at kernel/qeventdispatcher_glib.cpp:277 #17 0x003d8855 in g_main_context_dispatch () from /lib/libglib-2.0.so.0 #18 0x003dc668 in ?? () from /lib/libglib-2.0.so.0 #19 0x003dc848 in g_main_context_iteration () from /lib/libglib-2.0.so.0 #20 0x010979d8 in QEventDispatcherGlib::processEvents (this=0x8a13908, flags=...) at kernel/qeventdispatcher_glib.cpp:422 #21 0x0142ee2e in QGuiEventDispatcherGlib::processEvents (this=0x8a13908, flags=...) at kernel/qguieventdispatcher_glib.cpp:204 #22 0x0105c557 in QEventLoop::processEvents (this=0xbfbf697c, flags=...) at kernel/qeventloop.cpp:149 #23 0x0105c69c in QEventLoop::exec (this=0xbfbf697c, flags=...) at kernel/qeventloop.cpp:201 #24 0x0105f801 in QCoreApplication::exec () at kernel/qcoreapplication.cpp:1008 #25 0x013598fa in QApplication::exec () at kernel/qapplication.cpp:3736 #26 0x0773a871 in meth_QApplication_exec_ (sipArgs=0xb783202c) at sipQtGuiQApplication.cpp:2266 #27 0x00a69ba2 in PyCFunction_Call (func=0x8ef72cc, arg=0xb783202c, kw=0x0) at Objects/methodobject.c:81 #28 0x00ace901 in call_function (f=0x8f4725c, throwflag=0) at Python/ceval.c:4012 #29 PyEval_EvalFrameEx (f=0x8f4725c, throwflag=0) at Python/ceval.c:2665 #30 0x00aced7f in fast_function (f=0x8a135e4, throwflag=0) at Python/ceval.c:4098 #31 call_function (f=0x8a135e4, throwflag=0) at Python/ceval.c:4033 #32 PyEval_EvalFrameEx (f=0x8a135e4, throwflag=0) at Python/ceval.c:2665 #33 0x00aced7f in fast_function (f=0x85be15c, throwflag=0) at Python/ceval.c:4098 #34 call_function (f=0x85be15c, throwflag=0) at Python/ceval.c:4033 #35 PyEval_EvalFrameEx (f=0x85be15c, throwflag=0) at Python/ceval.c:2665 #36 0x00aced7f in fast_function (f=0x859e4bc, throwflag=0) at Python/ceval.c:4098 #37 call_function (f=0x859e4bc, throwflag=0) at Python/ceval.c:4033 #38 PyEval_EvalFrameEx (f=0x859e4bc, throwflag=0) at Python/ceval.c:2665 #39 0x00ad0270 in PyEval_EvalCodeEx (co=0xb7798e78, globals=0xb786135c, locals=0xb786135c, args=0x0, argcount=0, kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3252 #40 0x00ad03b3 in PyEval_EvalCode (co=0xb7798e78, globals=0xb786135c, locals=0xb786135c) at Python/ceval.c:666 #41 0x00acf7e6 in
Re: [PyQt] Leak found in PyQt version 4.8.5-1 / 4.8.5 win32 build
On Mon, 22 Aug 2011 20:00:31 +0200, Carl Wolff carl.wo...@imtech.nl wrote: Hello, the following piece of code leaks: import PyQt4.QtGui import PyQt4.QtCore import time app = PyQt4.QtGui.QApplication([]) mainWindow = PyQt4.QtGui.QMainWindow() while True: button = PyQt4.QtGui.QPushButton(mainWindow) button.parent().findChild(PyQt4.QtCore.QObject, foo) button.setParent(None) time.sleep(0.01) When the findChild call is not done this code does not leak. So the leak cause seems to be located somewhere in the findChild processing, or I must be doing something wrong. In older version 4.7.3-2 this leak was not there. Best regards. Carl. Fixed in tonight's snapshot - thanks. Phil ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] subtle bug in PyQt in combination with Python garbage collector
On Sat, 13 Aug 2011 10:05:14 -0600, Kovid Goyal ko...@kovidgoyal.net wrote: This bug has been present for a very long time. As a workaround in my projects, I disable the automatic garbage collector and run garbage collection manually in the GUI thread via QTimer. Here's the code to do that: class GarbageCollector(QObject): ''' Disable automatic garbage collection and instead collect manually every INTERVAL milliseconds. This is done to ensure that garbage collection only happens in the GUI thread, as otherwise Qt can crash. ''' INTERVAL = 5000 def __init__(self, parent, debug=False): QObject.__init__(self, parent) self.debug = debug self.timer = QTimer(self) self.timer.timeout.connect(self.check) self.threshold = gc.get_threshold() gc.disable() self.timer.start(self.INTERVAL) #gc.set_debug(gc.DEBUG_SAVEALL) def check(self): #return self.debug_cycles() l0, l1, l2 = gc.get_count() if self.debug: print ('gc_check called:', l0, l1, l2) if l0 self.threshold[0]: num = gc.collect(0) if self.debug: print ('collecting gen 0, found:', num, 'unreachable') if l1 self.threshold[1]: num = gc.collect(1) if self.debug: print ('collecting gen 1, found:', num, 'unreachable') if l2 self.threshold[2]: num = gc.collect(2) if self.debug: print ('collecting gen 2, found:', num, 'unreachable') def debug_cycles(self): gc.collect() for obj in gc.garbage: print (obj, repr(obj), type(obj)) Kovid. Thanks for the insight. Two solutions spring to mind... 1. Implement the above so that it is created when QThread.start() is called for the first time. 2. Change the SIP generated dtor code so that it calls deleteLater() if the object's thread is not the current one... if (QThread::currentThread() == obj-thread()) delete obj; else obj-deleteLater(); I'd prefer the latter (assuming it works). Thoughts? Phil ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] segfault when using Qt.QueuedConnection
I've tried to create a test case for the previously reported issue. It appears the bug does not appear when the queued slot call is made after the sender has been deleted, but only if the call is made while the sender is deleted. To run the case, use : python -m nose.core \\ test_qt_bindings.py:SignalSlotCase.test_queued_connection_after_delete The case is very sensitive to timings, so it might be needed to run a couple of time. One way or another the app gets corrupted after some time Test the behaviour of the qt bindings in various circumstances. import unittest import gc from PyQt4 import QtGui, QtCore # # some helper classes to create all kinds of weird object structures # class ReferenceHoldingBox(QtGui.QGroupBox): A group box holding references to the table view and the table model def __init__(self, model, table): QtGui.QGroupBox.__init__(self) self.model = model self.table = table class TableView( QtGui.QWidget ): A widget containg both a table and a groupbox that holds a reference to both the table and the model of the table def __init__( self, table_model ): super(TableView, self).__init__() widget_layout = QtGui.QVBoxLayout() table = QtGui.QTableView( self ) table.setModel( table_model ) widget_layout.addWidget( table ) widget_layout.addWidget( ReferenceHoldingBox( table_model, self ) ) self.setLayout( widget_layout ) class CyclicChildWidget(QtGui.QWidget): def __init__( self, parent ): super( CyclicChildWidget, self ).__init__( parent ) self._parent = parent class CyclicWidget(QtGui.QWidget): def __init__( self ): super( CyclicWidget, self ).__init__() CyclicChildWidget( self ) count_alive = lambda:sum( isinstance(o,CyclicWidget) for o in gc.get_objects() ) alive = lambda initial:count_alive()-initial class ModelViewRegister(QtCore.QObject): def __init__(self): super(ModelViewRegister, self).__init__() self.max_key = 0 self.model_by_view = dict() def register_model_view(self, model, view): self.max_key += 1 view.destroyed.connect( self._registered_object_destroyed ) self.model_by_view[self.max_key] = model view.setProperty( 'registered_key', self.max_key ) @QtCore.pyqtSlot(QtCore.QObject) def _registered_object_destroyed(self, qobject): key, _success = qobject.property('registered_key').toLongLong() del self.model_by_view[key] class TableViewCases(unittest.TestCase): Tests related to table views def setUp(self): from camelot.test import get_application self.app = get_application() def test_table_view_garbage_collection(self): Create a table view and force its garbage collection, while a common reference exists to both the table view and its model. when doing so without registering the model and the view to the ModelViewRegister, this will segfault. register = ModelViewRegister() for _i in range(100): class TableModelSubclass(QtGui.QStringListModel): pass model = TableModelSubclass() widget = TableView( model ) register.register_model_view(model, widget) gc.collect() class SignalEmitter(QtCore.QObject): my_signal = QtCore.pyqtSignal(object) def start_emitting(self, limit=1000): for _i in range(limit): o = object() self.my_signal.emit(o) class SignalReceiver(QtCore.QObject): @QtCore.pyqtSlot(object) def my_slot(self, obj): print self.sender() class GarbageCollectionCase( unittest.TestCase ): def setUp(self): self.application = QtGui.QApplication.instance() if not self.application: import sys self.application = QtGui.QApplication(sys.argv) def test_custom_garbage_collectory( self ): from camelot.view.model_thread.garbage_collector import GarbageCollector initial = count_alive() collector = GarbageCollector(None, debug=True) collector._threshold = [0, 0, 0] self.assertFalse( alive(initial) ) cycle = CyclicWidget() self.assertTrue( alive(initial) ) del cycle self.assertTrue( alive(initial) ) collector._check() self.assertFalse( alive(initial) ) def test_cyclic_dependency( self ): Create 2 widgets with a cyclic dependency, so that they can only be removed by the garbage collector, and then invoke the garbage collector in a different thread. # # dont run this test, since it will segfault the # interpreter # return initial = count_alive() #