How to check if an object has been deleted?

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
User avatar
chennes
Veteran
Posts: 3884
Joined: Fri Dec 23, 2016 3:38 pm
Location: Norman, OK, USA
Contact:

Re: How to check if an object has been deleted?

Post by chennes »

Keep in mind that the second argument to processEvents is the maximum amount of time that will be spent processing events, not some sort of guarantee that it will spend that much time. So if you really need to wait a fixed interval, you do still have to use a QTimer in conjunction with this technique.
Chris Hennes
Pioneer Library System
GitHub profile, LinkedIn profile, chrishennes.com
User avatar
Roy_043
Veteran
Posts: 8450
Joined: Thu Dec 27, 2018 12:28 pm

Re: How to check if an object has been deleted?

Post by Roy_043 »

Thanks again. I can't get this to work though:

Code: Select all

        obj = Draft.make_clone(box)

        if App.GuiUp:
            from PySide import QtCore
            i = 0

            def process_events(self):
                QtCore.QCoreApplication.processEvents(QtCore.QEventLoop.AllEvents, 10)

            while i < 10:
                i += 1
                _msg(str(i))
                QtCore.QTimer.singleShot(100, self.process_events)
The simplified code in my previous post does work. Note that the pending event is limited: reassign the DiffuseColor.
User avatar
chennes
Veteran
Posts: 3884
Joined: Fri Dec 23, 2016 3:38 pm
Location: Norman, OK, USA
Contact:

Re: How to check if an object has been deleted?

Post by chennes »

My strategy in Addon Manager looks like this:

Code: Select all

class Killer:
    def __init__(self):
        self.die = False
    def die(self):
        self.die = True
killer = Killer()
timer = QtCore.QTimer()
timer.timeout.connect(killer.die)
timer.setSingleShot(True)
self.test_object.start_work()
timer.start(100)
while not self.test_object.done and not killer.die:
    QtCore.QCoreApplication.processEvents(QtCore.QEventLoop.AllEvents, 10)
self.assertFalse(killer.die, "Test process was killed by timer")
self.assertTrue(self.test_object.done, "Test process did not complete")
Chris Hennes
Pioneer Library System
GitHub profile, LinkedIn profile, chrishennes.com
freedman
Veteran
Posts: 3441
Joined: Thu Mar 22, 2018 3:02 am
Location: Washington State, USA

Re: How to check if an object has been deleted?

Post by freedman »

Maybe I don't understand, are we talking about using a slot to detect?
"slotDeletedObject(data)"
User avatar
onekk
Veteran
Posts: 6146
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: How to check if an object has been deleted?

Post by onekk »

I've had same problem some time ago and solved with a try: except clause plus s check.

But scenario was different as I was trying to empty an already existent document.

Sadly I'm not actually near a computer so no code to post.

Maybe later hoping it will help.

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
openBrain
Veteran
Posts: 9034
Joined: Fri Nov 09, 2018 5:38 pm
Contact:

Re: How to check if an object has been deleted?

Post by openBrain »

@Roy_043 could you point to the code using the delay?
wmayer
Founder
Posts: 20243
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: How to check if an object has been deleted?

Post by wmayer »

Roy_043 wrote: Thu Jan 26, 2023 9:06 pm The delay in make_clone.py:
https://github.com/FreeCAD/FreeCAD/blob ... ne.py#L129
Maybe it's better to fix the root of the problem instead of adding a workaround for a workaround.
User avatar
Roy_043
Veteran
Posts: 8450
Joined: Thu Dec 27, 2018 12:28 pm

Re: How to check if an object has been deleted?

Post by Roy_043 »

I fully agree that workarounds should be avoided. But in this case a workaround helps fix an almost 5 year old bug (issue #5765). I can create an issue for the DiffuseColor update issue if that helps.
User avatar
onekk
Veteran
Posts: 6146
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: How to check if an object has been deleted?

Post by onekk »

I think this could be related also to the documentobjects deletions (Problem cited above).

if I not put (thanks to @edwilliams16 ) the check for obj.TypeId it raise an error about "trying to delete a deleted object" when recursively delete all the document objects, strange enough it detects that an object has been deleted..

Code: Select all

    objects = doc.Objects
    for obj in objects:
        if obj.TypeId in ("App::"):
            pass
        else:
            doc.removeObject(obj.Name)
Prior of these I had to use this code:

Code: Select all

    for obj in doc.Objects:

        try:
            doc.removeObject(obj.Name)
        except Exception:
            pass

So probably removeObject(obj.Name) operation is slow enough to create similar problems like those in this thread.

From what I remember it was more visible when you have some Boolean operations or similar construct that act like containers for other objects.

But I'm using my "impaired" memory so I can't judge as it is old probably there are some glitch.


Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
User avatar
chennes
Veteran
Posts: 3884
Joined: Fri Dec 23, 2016 3:38 pm
Location: Norman, OK, USA
Contact:

Re: How to check if an object has been deleted?

Post by chennes »

I think this should work to give you a 0.1 second delay before the test code continues, but during that delay allow the event loop to continue processing (which is critical here, since otherwise the delay timer within the test object doesn't run):

Code: Select all

obj = Draft.make_clone(box)

if App.GuiUp:
    from PySide import QtCore
    class DelayEnder:
        def __init__(self):
            self.delay_is_done = False
        def stop(self):
            self.delay_is_done = True
    ender = DelayEnder()
    timer = QtCore.QTimer()
    timer.timeout.connect(ender.stop)
    timer.setSingleShot(True)
    timer.start(100) # 100ms timer guarantees the loop below runs at least that long
    while not ender.delay_is_done:
        QtCore.QCoreApplication.processEvents(QtCore.QEventLoop.AllEvents)
Chris Hennes
Pioneer Library System
GitHub profile, LinkedIn profile, chrishennes.com
Post Reply