Re: [PyQt] why do closeEvent and destroyed slot not get called on accepting PyQt4 QDialog?

2011-04-08 Thread RuiDC

fantastic!, 
that was exactly the penny drop I was missing!

Lessons learned: 
1. Don't hook handler for destroyed signal onto the object being destroyed.
(seems obvious in retrospect)
2. QDialog.accept() does not fire closeEvent, even though it does get
destroyed - bug or documentation is misleading IMHO
3. The different syntax for hooking up to the signal - much simpler and more
pythonic

Now I can get rid of the sip.isdeleted(obj) workaround in my actual code,
yech!

Many thanks!

-- 
View this message in context: 
http://old.nabble.com/why-do-closeEvent-and-destroyed-slot-not-get-called-on-accepting-PyQt4-QDialog--tp31336229p31349767.html
Sent from the PyQt mailing list archive at Nabble.com.

___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] why do closeEvent and destroyed slot not get called on accepting PyQt4 QDialog?

2011-04-07 Thread Hans-Peter Jansen
On Thursday 07 April 2011, 17:27:15 Rui DaCosta wrote:
> Firstly thanks again for your reply,
>
> In the original code, from where this simplification is based, I have
> cleanup code on both closeEvent and destroyed, but...
>
> that's just the problem, the closeEvent isn't getting fired (unless I
> manually call close) - except when the window is closed from the
> close box.
>
> I was expecting that from the docs for done(), I would not have to on
> done(), ie. is this a bug? or are the docs incorrect?
>
> And separately,  destroyed is a signal according to the docs
> http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qobject.ht
>ml#destroyed
>
>
> but I cannot get it to fire for QDialog, no matter what I do,
> including manually calling destroy().
>
> The object appears deleted when inspected with sip.isdeleted, even
> before the destroy() - so if that is the case, why does it not raise
> a destroyed signal?

Well, looks like this is an issue in Heisenbergs uncertainty principle
domain ;-)

It's simply the GC, that's in the way. If you anchor the connect 
somewhere else, the destroyed signal "gets though". If your real dialog
has a parent, you might get away with anchoring the connect there.

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *

def pr(arg):
sys.stdout.write(arg + "\n")
sys.stdout.flush()

class Dialog(QDialog):
def __init__(self):
QDialog.__init__(self, None, Qt.WindowFlags(Qt.WA_DeleteOnClose))
self.button_box = QDialogButtonBox(self)
self.button_box.addButton(self.button_box.Ok)
self.button_box.accepted.connect(self.on_accept)
layout = QVBoxLayout()
layout.addWidget(self.button_box)
#self.setAttribute(Qt.WA_DeleteOnClose)
self.setLayout(layout)
self.destroyed.connect(self.on_destroyed)

def on_destroyed(self, *args):
pr("destroying dialog")

def on_accept(self):
pr("accepting")
self.done(42)

def closeEvent(self, event):
pr("close")
return QDialog.closeEvent(self, event)


app = QApplication([])
widget = Dialog()
widget.destroyed.connect(lambda: pr("destroyed"))
result = widget.exec_()
del widget
#my_widget.destroy()
print("result: %s" % result)



>
>
>
>
>
> ____________
> From: Demetrius Cassidy 
> To: Rui DaCosta 
> Cc: pyqt@riverbankcomputing.com
> Sent: Thu, 7 April, 2011 17:02:04
> Subject: Re: [PyQt] why do closeEvent and destroyed slot not get
> called on accepting PyQt4 QDialog?
>
>
> I truly believe you are approaching this from the wrong angle. If you
> need to know when your QDialog is going away, you override closeEvent
> and do your cleanup from there.
>
> However, looking through the docs, it does not appear that destroy is
> actually a signal. It's called from the QWidget dtor, so it makes
> sense that if you call destroy(), you get the runtime error because
> you are deleting the C++ object before the Python object. Do not call
> destroy yourself - call self.close and override closeEvent. From
> there you can accept or reject closing the dialog, and do any cleanup
> prior to your dialog being destroyed.
>
> From the Qt Docs:
>
> void QWidget::destroy ( bool destroyWindow = true, bool
> destroySubWindows = true ) [protected]
>
> Frees up window system resources. Destroys the widget window if
> destroyWindow is true.
>
> destroy() calls itself recursively for all the child widgets, passing
> destroySubWindows for the destroyWindow parameter. To have more
> control over destruction of subwidgets, destroy subwidgets
> selectively first.
>
> This function is usually called from the QWidget destructor.
>
>
> On Thu, Apr 7, 2011 at 3:04 AM, Rui DaCosta  wrote:
>
> I know it can close it manually, the problem is that this is a
> simplification of a problem I had, in which we were expecting the
> QDialog to close as per the docs, but it did not.
>
> >The *real* problem we are facing, is a bit further down the line,
> > where we are getting the "RuntimeError: underlying C/C++ object has
> > been deleted" but we never receive a destroyed signal.
> >The only reason I need this signal or event is to do some teardown
> > code for some callbacks to avoid getting this c++ error elsewhere.
>
> 
> From: Demetrius Cassidy 
>
> >To: RuiDC 
> >Sent: Thu, 7 April, 2011 0:39:33
> >Subject: Re: [PyQt] why do closeEvent and destroyed slot not get
> > called on accepting PyQt4 QDialog?
> >
> >
> >If you want to close, just call self.close. It's a slot, so you can
> > map it to any 

Re: [PyQt] why do closeEvent and destroyed slot not get called on accepting PyQt4 QDialog?

2011-04-07 Thread Rui DaCosta
just to be clear, I wasn't trying to use destroy(), I was merely using it to 
demonstrate that even if I did, neither the closeEvent nor the destroyed signal 
were working.





From: Demetrius Cassidy 
To: Rui DaCosta 
Cc: pyqt@riverbankcomputing.com
Sent: Thu, 7 April, 2011 17:18:29
Subject: Re: [PyQt] why do closeEvent and destroyed slot not get called on 
accepting PyQt4 QDialog?

Sorry found destroyed() - that's what happens when you reply to emails before 
you have morning coffee. Anyway I'm not sure why destroyed() is never fired. I 
tried your code and even modified it a bit to use the new style slots and 
signals but it's not being fired.


Either way, I think the other points I raised in my last email are still valid. 
IMHO using destroyed() in python is the wrong approach.

On Thu, Apr 7, 2011 at 11:02 AM, Demetrius Cassidy  wrote:

I truly believe you are approaching this from the wrong angle. If you need to 
know when your QDialog is going away, you override closeEvent and do your 
cleanup from there. 
>
>
>However, looking through the docs, it does not appear that destroy is actually 
>a 
>signal. It's called from the QWidget dtor, so it makes sense that if you call 
>destroy(), you get the runtime error because you are deleting the C++ object 
>before the Python object. Do not call destroy yourself - call self.close and 
>override closeEvent. From there you can accept or reject closing the dialog, 
>and 
>do any cleanup prior to your dialog being destroyed.
>
>
>From the Qt Docs:
>
>
>void QWidget::destroy ( bool destroyWindow = true, bool destroySubWindows = 
>true 
>) [protected]
>
>Frees up window system resources. Destroys the widget window if destroyWindow 
>is 
>true.
>
>destroy() calls itself recursively for all the child widgets, passing 
>destroySubWindows for the destroyWindow parameter. To have more control over 
>destruction of subwidgets, destroy subwidgets selectively first.
>
>This function is usually called from the QWidget destructor.
>
>
>
>On Thu, Apr 7, 2011 at 3:04 AM, Rui DaCosta  wrote:
>
>I know it can close it manually, the problem is that this is a simplification 
>of 
>a problem I had, in which we were expecting the QDialog to close as per the 
>docs, but it did not.
>>The *real* problem we are facing, is a bit further down the line, where we 
>>are 
>>getting the "RuntimeError: underlying C/C++ object has been deleted" but we 
>>never receive a destroyed signal.
>>The only reason I need this signal or event is to do some teardown code for 
>>some 
>>callbacks to avoid getting this c++ error elsewhere.
>>
>>
>>
>>

From: Demetrius Cassidy 
>>To: RuiDC 
>>Sent: Thu, 7 April, 2011 0:39:33
>>Subject: Re: [PyQt] why do closeEvent and destroyed slot not get called on 
>>accepting PyQt4 QDialog?
>>
>>
>>If you want to close, just call self.close. It's a slot, so you can map it to 
>>any signal. Also not sure why you want to know when your widget is destroyed? 
>>Let Python take care of it, you should not need to call sip.delete yourself. 
>>closeEvent is there if you need to know _when_ your app was requested to 
>>close. 
>>If you want to allow or reject closing the app, you need to use the QEvent 
>>object which gets passed to that function. 
>>
>>
>>On Wed, Apr 6, 2011 at 5:27 PM, RuiDC  wrote:
>>
>>
>>>The question & code are here:
>>>http://stackoverflow.com/questions/5570402/why-do-closeevent-and-destroyed-slot-not-get-called-on-accepting-pyqt4-qdialog
>>>
>>>
>>>but hopefully someone here can give me an answer on:
>>>1. how to get the closeEvent to fire from accepting (or do I have to do a
>>>self.close()?)
>>>2. how to get the destroyed message to print (or do I have to go through
>>>sip.delete(my_widget)?)
>>>3. why, if I comment out the del my_widget, and uncomment the
>>>my_widget.destroy() I get a:
>>>RuntimeError: underlying C/C++ object has been deleted
>>>on the destroy() without the print!  i.e. how is it that it can be destroyed
>>>but not raise the signal?
>>>
>>>Thanks in advance,
>>>R
>>>--
>>>View this message in context: 
>>>http://old.nabble.com/why-do-closeEvent-and-destroyed-slot-not-get-called-on-accepting-PyQt4-QDialog--tp31336229p31336229.html
>>>
>>>Sent from the PyQt mailing list archive at Nabble.com.
>>>
>>>___
>>>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] why do closeEvent and destroyed slot not get called on accepting PyQt4 QDialog?

2011-04-07 Thread Rui DaCosta
Firstly thanks again for your reply, 

In the original code, from where this simplification is based, I have cleanup 
code on both closeEvent and destroyed, but...

that's just the problem, the closeEvent isn't getting fired (unless I manually 
call close) - except when the window is closed from the close box. 

I was expecting that from the docs for done(), I would not have to on done(), 
ie. is this a bug? or are the docs incorrect?

And separately,  destroyed is a signal according to the docs 
http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qobject.html#destroyed


but I cannot get it to fire for QDialog, no matter what I do, including 
manually 
calling destroy(). 

The object appears deleted when inspected with sip.isdeleted, even before the 
destroy() - so if that is the case, why does it not raise a destroyed signal?







From: Demetrius Cassidy 
To: Rui DaCosta 
Cc: pyqt@riverbankcomputing.com
Sent: Thu, 7 April, 2011 17:02:04
Subject: Re: [PyQt] why do closeEvent and destroyed slot not get called on 
accepting PyQt4 QDialog?


I truly believe you are approaching this from the wrong angle. If you need to 
know when your QDialog is going away, you override closeEvent and do your 
cleanup from there. 

However, looking through the docs, it does not appear that destroy is actually 
a 
signal. It's called from the QWidget dtor, so it makes sense that if you call 
destroy(), you get the runtime error because you are deleting the C++ object 
before the Python object. Do not call destroy yourself - call self.close and 
override closeEvent. From there you can accept or reject closing the dialog, 
and 
do any cleanup prior to your dialog being destroyed.

From the Qt Docs:

void QWidget::destroy ( bool destroyWindow = true, bool destroySubWindows = 
true 
) [protected]

Frees up window system resources. Destroys the widget window if destroyWindow 
is 
true.

destroy() calls itself recursively for all the child widgets, passing 
destroySubWindows for the destroyWindow parameter. To have more control over 
destruction of subwidgets, destroy subwidgets selectively first.

This function is usually called from the QWidget destructor.


On Thu, Apr 7, 2011 at 3:04 AM, Rui DaCosta  wrote:

I know it can close it manually, the problem is that this is a simplification 
of 
a problem I had, in which we were expecting the QDialog to close as per the 
docs, but it did not.
>The *real* problem we are facing, is a bit further down the line, where we are 
>getting the "RuntimeError: underlying C/C++ object has been deleted" but we 
>never receive a destroyed signal.
>The only reason I need this signal or event is to do some teardown code for 
>some 
>callbacks to avoid getting this c++ error elsewhere.
>
>
>
>

From: Demetrius Cassidy 
>To: RuiDC 
>Sent: Thu, 7 April, 2011 0:39:33
>Subject: Re: [PyQt] why do closeEvent and destroyed slot not get called on 
>accepting PyQt4 QDialog?
>
>
>If you want to close, just call self.close. It's a slot, so you can map it to 
>any signal. Also not sure why you want to know when your widget is destroyed? 
>Let Python take care of it, you should not need to call sip.delete yourself. 
>closeEvent is there if you need to know _when_ your app was requested to 
>close. 
>If you want to allow or reject closing the app, you need to use the QEvent 
>object which gets passed to that function. 
>
>
>On Wed, Apr 6, 2011 at 5:27 PM, RuiDC  wrote:
>
>
>>The question & code are here:
>>http://stackoverflow.com/questions/5570402/why-do-closeevent-and-destroyed-slot-not-get-called-on-accepting-pyqt4-qdialog
>>
>>
>>but hopefully someone here can give me an answer on:
>>1. how to get the closeEvent to fire from accepting (or do I have to do a
>>self.close()?)
>>2. how to get the destroyed message to print (or do I have to go through
>>sip.delete(my_widget)?)
>>3. why, if I comment out the del my_widget, and uncomment the
>>my_widget.destroy() I get a:
>>RuntimeError: underlying C/C++ object has been deleted
>>on the destroy() without the print!  i.e. how is it that it can be destroyed
>>but not raise the signal?
>>
>>Thanks in advance,
>>R
>>--
>>View this message in context: 
>>http://old.nabble.com/why-do-closeEvent-and-destroyed-slot-not-get-called-on-accepting-PyQt4-QDialog--tp31336229p31336229.html
>>
>>Sent from the PyQt mailing list archive at Nabble.com.
>>
>>___
>>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] why do closeEvent and destroyed slot not get called on accepting PyQt4 QDialog?

2011-04-07 Thread Demetrius Cassidy
Sorry found destroyed() - that's what happens when you reply to emails
before you have morning coffee. Anyway I'm not sure why destroyed() is never
fired. I tried your code and even modified it a bit to use the new style
slots and signals but it's not being fired.

Either way, I think the other points I raised in my last email are still
valid. IMHO using destroyed() in python is the wrong approach.

On Thu, Apr 7, 2011 at 11:02 AM, Demetrius Cassidy wrote:

> I truly believe you are approaching this from the wrong angle. If you need
> to know when your QDialog is going away, you override closeEvent and do your
> cleanup from there.
>
> However, looking through the docs, it does not appear that destroy is
> actually a signal. It's called from the QWidget dtor, so it makes sense that
> if you call destroy(), you get the runtime error because you are deleting
> the C++ object before the Python object. Do not call destroy yourself - call
> self.close and override closeEvent. From there you can accept or reject
> closing the dialog, and do any cleanup prior to your dialog being destroyed.
>
> From the Qt Docs:
>
> void QWidget::destroy ( bool destroyWindow = true, bool destroySubWindows =
> true ) [protected]
>
> Frees up window system resources. Destroys the widget window if
> destroyWindow is true.
>
> destroy() calls itself recursively for all the child widgets, passing
> destroySubWindows for the destroyWindow parameter. To have more control over
> destruction of subwidgets, destroy subwidgets selectively first.
>
> This function is usually called from the QWidget destructor.
>
> On Thu, Apr 7, 2011 at 3:04 AM, Rui DaCosta  wrote:
>
>> I know it can close it manually, the problem is that this is a
>> simplification of a problem I had, in which we were expecting the QDialog to
>> close as per the docs, but it did not.
>> The *real* problem we are facing, is a bit further down the line, where we
>> are getting the "RuntimeError: underlying C/C++ object has been deleted"
>> but we never receive a destroyed signal.
>> The only reason I need this signal or event is to do some teardown code
>> for some callbacks to avoid getting this c++ error elsewhere.
>>
>> ------------------
>> *From:* Demetrius Cassidy 
>> *To:* RuiDC 
>> *Sent:* Thu, 7 April, 2011 0:39:33
>> *Subject:* Re: [PyQt] why do closeEvent and destroyed slot not get called
>> on accepting PyQt4 QDialog?
>>
>> If you want to close, just call self.close. It's a slot, so you can map it
>> to any signal. Also not sure why you want to know when your widget is
>> destroyed? Let Python take care of it, you should not need to call
>> sip.delete yourself. closeEvent is there if you need to know _when_ your app
>> was requested to close. If you want to allow or reject closing the app, you
>> need to use the QEvent object which gets passed to that function.
>>
>> On Wed, Apr 6, 2011 at 5:27 PM, RuiDC  wrote:
>>
>>>
>>> The question & code are here:
>>>
>>> http://stackoverflow.com/questions/5570402/why-do-closeevent-and-destroyed-slot-not-get-called-on-accepting-pyqt4-qdialog
>>>
>>> but hopefully someone here can give me an answer on:
>>> 1. how to get the closeEvent to fire from accepting (or do I have to do a
>>> self.close()?)
>>> 2. how to get the destroyed message to print (or do I have to go through
>>> sip.delete(my_widget)?)
>>> 3. why, if I comment out the del my_widget, and uncomment the
>>> my_widget.destroy() I get a:
>>> RuntimeError: underlying C/C++ object has been deleted
>>> on the destroy() without the print!  i.e. how is it that it can be
>>> destroyed
>>> but not raise the signal?
>>>
>>> Thanks in advance,
>>> R
>>> --
>>> View this message in context:
>>> http://old.nabble.com/why-do-closeEvent-and-destroyed-slot-not-get-called-on-accepting-PyQt4-QDialog--tp31336229p31336229.html
>>> Sent from the PyQt mailing list archive at Nabble.com.
>>>
>>> ___
>>> 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] why do closeEvent and destroyed slot not get called on accepting PyQt4 QDialog?

2011-04-07 Thread Demetrius Cassidy
I truly believe you are approaching this from the wrong angle. If you need
to know when your QDialog is going away, you override closeEvent and do your
cleanup from there.

However, looking through the docs, it does not appear that destroy is
actually a signal. It's called from the QWidget dtor, so it makes sense that
if you call destroy(), you get the runtime error because you are deleting
the C++ object before the Python object. Do not call destroy yourself - call
self.close and override closeEvent. From there you can accept or reject
closing the dialog, and do any cleanup prior to your dialog being destroyed.

>From the Qt Docs:

void QWidget::destroy ( bool destroyWindow = true, bool destroySubWindows =
true ) [protected]

Frees up window system resources. Destroys the widget window if
destroyWindow is true.

destroy() calls itself recursively for all the child widgets, passing
destroySubWindows for the destroyWindow parameter. To have more control over
destruction of subwidgets, destroy subwidgets selectively first.

This function is usually called from the QWidget destructor.

On Thu, Apr 7, 2011 at 3:04 AM, Rui DaCosta  wrote:

> I know it can close it manually, the problem is that this is a
> simplification of a problem I had, in which we were expecting the QDialog to
> close as per the docs, but it did not.
> The *real* problem we are facing, is a bit further down the line, where we
> are getting the "RuntimeError: underlying C/C++ object has been deleted"
> but we never receive a destroyed signal.
> The only reason I need this signal or event is to do some teardown code for
> some callbacks to avoid getting this c++ error elsewhere.
>
> --
> *From:* Demetrius Cassidy 
> *To:* RuiDC 
> *Sent:* Thu, 7 April, 2011 0:39:33
> *Subject:* Re: [PyQt] why do closeEvent and destroyed slot not get called
> on accepting PyQt4 QDialog?
>
> If you want to close, just call self.close. It's a slot, so you can map it
> to any signal. Also not sure why you want to know when your widget is
> destroyed? Let Python take care of it, you should not need to call
> sip.delete yourself. closeEvent is there if you need to know _when_ your app
> was requested to close. If you want to allow or reject closing the app, you
> need to use the QEvent object which gets passed to that function.
>
> On Wed, Apr 6, 2011 at 5:27 PM, RuiDC  wrote:
>
>>
>> The question & code are here:
>>
>> http://stackoverflow.com/questions/5570402/why-do-closeevent-and-destroyed-slot-not-get-called-on-accepting-pyqt4-qdialog
>>
>> but hopefully someone here can give me an answer on:
>> 1. how to get the closeEvent to fire from accepting (or do I have to do a
>> self.close()?)
>> 2. how to get the destroyed message to print (or do I have to go through
>> sip.delete(my_widget)?)
>> 3. why, if I comment out the del my_widget, and uncomment the
>> my_widget.destroy() I get a:
>> RuntimeError: underlying C/C++ object has been deleted
>> on the destroy() without the print!  i.e. how is it that it can be
>> destroyed
>> but not raise the signal?
>>
>> Thanks in advance,
>> R
>> --
>> View this message in context:
>> http://old.nabble.com/why-do-closeEvent-and-destroyed-slot-not-get-called-on-accepting-PyQt4-QDialog--tp31336229p31336229.html
>> Sent from the PyQt mailing list archive at Nabble.com.
>>
>> ___
>> 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] why do closeEvent and destroyed slot not get called on accepting PyQt4 QDialog?

2011-04-06 Thread RuiDC

The question & code are here:
http://stackoverflow.com/questions/5570402/why-do-closeevent-and-destroyed-slot-not-get-called-on-accepting-pyqt4-qdialog

but hopefully someone here can give me an answer on:
1. how to get the closeEvent to fire from accepting (or do I have to do a
self.close()?)
2. how to get the destroyed message to print (or do I have to go through
sip.delete(my_widget)?)
3. why, if I comment out the del my_widget, and uncomment the
my_widget.destroy() I get a:
RuntimeError: underlying C/C++ object has been deleted
on the destroy() without the print!  i.e. how is it that it can be destroyed
but not raise the signal?

Thanks in advance,
R
-- 
View this message in context: 
http://old.nabble.com/why-do-closeEvent-and-destroyed-slot-not-get-called-on-accepting-PyQt4-QDialog--tp31336229p31336229.html
Sent from the PyQt mailing list archive at Nabble.com.

___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt