Dialogs and PyDeadObjectError

Hi,

rarely I run into PyDeadObjectErrors when accessing a python-property of
the wrapped wxDialog object, after the dialog was closed.

For example:

class MyDialog(wx.Dialog):
    def __init__(self, *args, **kwargs):
        wx.Dialog.__init__(self, *args, **kwargs)
        self.myProp = 1

dlg = MyDialog(...).ShowModal()

...do something for 1 or 2 seconds...

print dlg.myProp # rarely raises PyDeadObjectError

So I guess the problem is that in those 1 or 2 seconds the C++ object of
the dialog was deleted and dlg changed its type to the PyDeadObject-class.

When actually is the C++-dialog-object being deleted? What will trigger it?

Should I also be afraid of (rarely) getting a PyDeadObjectError when
using common dialogs, f.i. FileDialog, and access the
FileDialog.GetPath()-method some seconds after the dialog was closed?

Thanks, Regards, Frank

You should always get your data from the dialog BEFORE you close it and it gets destroyed. You can do that by using a conditional like “if dlg.ShowModal() == wx.ID_OK:” then you can pull information from it by doing something like “value = dlg.myTextbox.GetValue()”

Or you could use your dialog’s closing event to pass data back using pubsub too, although I think that’s usually overkill

···

Mike Driscoll

Blog: http://blog.pythonlibrary.org

Hi,

rarely I run into PyDeadObjectErrors when accessing a python-property of
the wrapped wxDialog object, after the dialog was closed.

For example:

class MyDialog(wx.Dialog):
     def __init__(self, *args, **kwargs):
         wx.Dialog.__init__(self, *args, **kwargs)
         self.myProp = 1

dlg = MyDialog(...).ShowModal()

...do something for 1 or 2 seconds...

print dlg.myProp # rarely raises PyDeadObjectError

So I guess the problem is that in those 1 or 2 seconds the C++ object of
the dialog was deleted and dlg changed its type to the PyDeadObject-class.

What kinds of things are you doing during that 1 or 2 seconds?

When actually is the C++-dialog-object being deleted? What will trigger it?

It shouldn't be until you call its Destroy method or, if there is a parent, when the parent is destroyed. If it's happening before that then please make a small runnable sample that duplicates the problem so I can take a deeper look at it. MakingSampleApps - wxPyWiki

Should I also be afraid of (rarely) getting a PyDeadObjectError when
using common dialogs, f.i. FileDialog, and access the
FileDialog.GetPath()-method some seconds after the dialog was closed?

No, but there really shouldn't be any need to hold on to them for that long is there? Just grab the values you need from them and continue on.

···

On 11/17/11 9:47 AM, Frank Hempel wrote:

--
Robin Dunn
Software Craftsman

I think I found the/my problem. In this 1 or 2 seconds a file is
uploaded, but in a synchronous manner which led me think that the wx
mainloop could not run. But that's not true for the code I'm confronted
to. The upload has the posibility to show progress and therefor it calls
wx.YieldIfNeeded(). That's why there were occasions for wx to do
something, for example cleanup the dialog cpp-object.

So all I need to do is grab evreything from the dialog after ShowModal()
returns and I'm fine.

Thanks, Regards, Frank

···

Am 17.11.2011 21:33, schrieb Robin Dunn:

On 11/17/11 9:47 AM, Frank Hempel wrote:

Hi,

rarely I run into PyDeadObjectErrors when accessing a python-property of
the wrapped wxDialog object, after the dialog was closed.

For example:

class MyDialog(wx.Dialog):
     def __init__(self, *args, **kwargs):
         wx.Dialog.__init__(self, *args, **kwargs)
         self.myProp = 1

dlg = MyDialog(...).ShowModal()

...do something for 1 or 2 seconds...

print dlg.myProp # rarely raises PyDeadObjectError

So I guess the problem is that in those 1 or 2 seconds the C++ object of
the dialog was deleted and dlg changed its type to the
PyDeadObject-class.

What kinds of things are you doing during that 1 or 2 seconds?

"Just grab the values "
"I need to do is grab evreything from the dialog "

I was wondering, do most of you "pull" data from other widgets, say
you pull data from a dialog box from the source code of a parent frame
for example? Meaning, in the parent frame, you have code that reads
attributes from the dialog widget;

Or do most of you "push" your data? Something I always thought, for
whatever reason, to be more reliable. Pushing would be the dialog
widget code modifies some "storage" attribute in the dialog box's
parent widget, its frame for exampe, -before- the dialog box closes.

I think for me it depends on what the dialog is for. If it’s for adding a record, then it just gets saved to a database. If it’s simple, I’ll probably use the “pull” method. If it’s non-trivial, then I’ll use pubsub.

···

Mike Driscoll

Blog: http://blog.pythonlibrary.org

What signal does your parent use to know when to poll for the dialog
box's data? On the DialogBox OK click?

Is a typical senario: user clicks the dialog box's OK button, you hide
the dialog box, then set the focus elsewhere, then retrieve the dialog
data, and then finally destroy the dialog box?

Personally I'm not a dialog box fan.

···

On Nov 21, 4:43 pm, Mike Driscoll <kyoso...@gmail.com> wrote:

I think for me it depends on what the dialog is for. If it's for adding a
record, then it just gets saved to a database. If it's simple, I'll
probably use the "pull" method. If it's non-trivial, then I'll use pubsub.
Mike Driscoll

"Just grab the values"
"I need to do is grab evreything from the dialog"

I was wondering, do most of you "pull" data from other widgets, say
you pull data from a dialog box from the source code of a parent frame
for example? Meaning, in the parent frame, you have code that reads
attributes from the dialog widget;

It depends whether the widget is shown modal or unmodal. Speaking for a dialog, pulling data out after it was closed with a "positive" return value is what I usualy do.

Or do most of you "push" your data? Something I always thought, for
whatever reason, to be more reliable. Pushing would be the dialog
widget code modifies some "storage" attribute in the dialog box's
parent widget, its frame for exampe, -before- the dialog box closes.

Speaking again for modal dialogs, you should be aware that a dialog can be canceled. So you need a way to rollback the changes you have done during the modal dialog session. If this needs a lot of extra coding I recommend the first way (pull after close). If a rollback is easy, f.i. when you have transactional aware objects which only need a abort/rollback-call to mutate to its state as before the dialog was shown, I have also gone this way.

Regards, Frank

···

Am 21.11.2011 22:23, schrieb DevPlayer:

Makes sense.

I use a similar approach to Mike's.

A sample:

A supplier dialog (could actually be any or my master data type dialogs), which allows to enter all the information about a supplier. These dialogs have a objectlistview with search and allow create/update/delete on a pane (or if there is lots of information there might be a aui.notebook) below the list.

- it is called in my case from e.g. a wine detail frame/pane, when closed (either via ok/close button or by double clicking an existing entry) the parent does dlg.GetLastSelection() which returns the primary key of the selected supplier or None.

- as the table is also used on other panes I also use pubsub. The dialog on save or delete does this:

             pub.sendMessage(pTopics.searchControl.updated,
                             tablename=self.baseTable)

The search control subscribes to this and does what is needed next time the user wants to search.

Werner

···

On 11/21/2011 10:53 PM, DevPlayer wrote:

On Nov 21, 4:43 pm, Mike Driscoll<kyoso...@gmail.com> wrote:

I think for me it depends on what the dialog is for. If it's for adding a
record, then it just gets saved to a database. If it's simple, I'll
probably use the "pull" method. If it's non-trivial, then I'll use pubsub.
Mike Driscoll

What signal does your parent use to know when to poll for the dialog
box's data? On the DialogBox OK click?

Is a typical senario: user clicks the dialog box's OK button, you hide
the dialog box, then set the focus elsewhere, then retrieve the dialog
data, and then finally destroy the dialog box?

Personally I'm not a dialog box fan.

Yeah, I grab the data when the user presses the OK button. But I don’t hide the dialog, I destroy it. There’s no need for the intermediate step of hiding it. I don’t use dialogs that much either. I tend to use frames. Dialogs are usually used for alerting users that they’ve made a mistake or for my About screen.

···

Mike Driscoll

Blog: http://blog.pythonlibrary.org

I don’t make any changes until AFTER the dialog is closed, so I never need to bother with rollback code. If the user cancels the dialog, it gets destroyed along with all the data the user entered.

···

On Mon, Nov 21, 2011 at 3:57 PM, Frank Hempel red_socks@gmx.de wrote:

Am 21.11.2011 22:23, schrieb DevPlayer:

“Just grab the values”

“I need to do is grab evreything from the dialog”

I was wondering, do most of you “pull” data from other widgets, say

you pull data from a dialog box from the source code of a parent frame

for example? Meaning, in the parent frame, you have code that reads

attributes from the dialog widget;

It depends whether the widget is shown modal or unmodal. Speaking for a dialog, pulling data out after it was closed with a “positive” return value is what I usualy do.

Or do most of you “push” your data? Something I always thought, for

whatever reason, to be more reliable. Pushing would be the dialog

widget code modifies some “storage” attribute in the dialog box’s

parent widget, its frame for exampe, -before- the dialog box closes.

Speaking again for modal dialogs, you should be aware that a dialog can be canceled. So you need a way to rollback the changes you have done during the modal dialog session. If this needs a lot of extra coding I recommend the first way (pull after close). If a rollback is easy, f.i. when you have transactional aware objects which only need a abort/rollback-call to mutate to its state as before the dialog was shown, I have also gone this way.

Regards, Frank


Mike Driscoll

Blog: http://blog.pythonlibrary.org

Things I use to decide:
- a menu is needed = frame
- a toolbar is needed = frame or aui in a frame or dialog
- short lived sub-data entry = dialog
- info message = dialog

- application (the main screen) = frame

Frank's point on rollback is something which I am not always sure how to handle.

What is a users expectation when he/she creates a supplier which is done on a separate screen from the main application in which the user just created some record (a wine, a purchase order etc).

On the supplier screen he/she had a save button and pressed it but then for some reason on the main screen the user decides to abort. Should the rollback affect the "saved" data from the supplier screen.

I normally handle the supplier dialog as a separate transaction (so it is not affected by the rollback) as I think it is more confusing when it disappears after user aborted a purchase.

Werner

···

On 11/22/2011 03:45 PM, Mike Driscoll wrote:

Yeah, I grab the data when the user presses the OK button. But I don't hide the dialog, I destroy it. There's no need for the intermediate step of hiding it. I don't use dialogs that much either. I tend to use frames. Dialogs are usually used for alerting users that they've made a mistake or for my About screen.

It's nice to see other's thoughts on this.