On Tue, Mar 26, 2024, 5:35 AM Juan Cristóbal Quesada < juan.cristobal...@gmail.com> wrote:
> i just ask chatgpt what good practices are. > i m glad to know that keeping a "global" reference prevents them to be > deleted. > Apart from what Justin said regarding the parent-child relationship. > I guess that is all we should care about. > > I had a very specific use case, where a derived QWidget class was > implementing an interface that would realize a method. > The thing is, when this object/method was being called as a result of a > publish/subscriber event, accessing the object was causing the C++ already > deleted object RuntimeError. > > All i did is have the class derive from a base one that registers and > holds widgets in a static list. Problem, apparently gone. > In this particular use case, without the static list, were you only passing a method of the object to a slot and there was no other reference to the object being held, and no parent set? > El lun, 25 mar 2024 a las 11:37, Juan Cristóbal Quesada (< > juan.cristobal...@gmail.com>) escribió: > >> When working with PySide objects, especially when interacting with Qt >> objects implemented in C++, it's important to handle references correctly >> to avoid memory issues and potential segmentation faults. Here are some >> good programming practices to follow: >> >> 1. Parenting: Assign a parent to PySide objects whenever possible. >> When an object has a parent, it will be automatically deleted when its >> parent is deleted. This helps avoid memory leaks and ensures cleaner >> object >> management. >> >> pythonCopy code >> # Example of creating a widget with a parent >> parent_widget = QtWidgets.QWidget() >> child_widget = QtWidgets.QWidget(parent_widget) >> >> >> 1. Maintain references: Ensure that you maintain references to >> objects as long as you need them. If an object is a local variable in a >> function and goes out of scope, it will be automatically destroyed, which >> can cause issues if it's still needed. >> >> pythonCopy code >> # Example of maintaining a global reference >> global_object = None >> def create_object(): >> global global_object >> global_object = QtWidgets.QWidget() >> >> create_object()# 'global_object' is still accessible here >> >> >> 1. Use Python's garbage collector: Python's garbage collector can >> clean up objects that are no longer in use, but you shouldn't rely solely >> on it to manage PySide objects. It's always better to explicitly release >> resources when they're no longer needed. >> >> pythonCopy code >> # Example of explicit resource release >> widget = QtWidgets.QWidget() >> widget.setParent(None) # Release the object from the parent >> widget.deleteLater() # Mark the object to be deleted later >> >> >> 1. Avoid reference cycles: Avoid creating object structures that form >> reference cycles, as this can prevent Python's garbage collector from >> properly releasing memory. >> >> pythonCopy code >> # Example of reference cycle >> widget1 = QtWidgets.QWidget() >> widget2 = QtWidgets.QWidget() >> widget1.child = widget2 >> widget2.parent = widget1 >> >> By following these good programming practices, you can handle PySide >> objects more safely and efficiently, minimizing the chances of encountering >> issues related to memory management. >> ChatGPT can make mistakes. Consider checking important information. >> >> El dom, 24 mar 2024 a las 19:39, Justin Israel (<justinisr...@gmail.com>) >> escribió: >> >>> I'm not familiar with the widget being deleted during some intermediate >>> operations. Pyside has had some weird bugs related to python garbage >>> collection over the years, but from my understanding they have been >>> addressed in modern releases. Could still be edge cases or maybe an older >>> Pyside version. Would be great to see a repo of the problem. >>> You should be able to parent the widget to something, and just not show >>> it. Adding it to a layout later would automatically reparent it. >>> >>> >>> On Mon, Mar 25, 2024, 12:41 AM Juan Cristóbal Quesada < >>> juan.cristobal...@gmail.com> wrote: >>> >>>> Yeah, as i understand, it is good practice whenever you instantiate a >>>> PySide object to, right after, to add it to a layout, which by default >>>> would set its parent widget to the widget that holds the layout and keep >>>> the hierarchy consistent. >>>> The problem arises when this is not always done and you want to >>>> instantiate a QWidget class without providing a parent right away, and >>>> perform some intermediate operations first. >>>> >>>> Then, situations like the one Chris shows, passing a python reference >>>> to a class and use it afterwards cause problems. That is why i was >>>> wondering if having a "class attribute" or "static attribute" would help >>>> there? >>>> It is easy to instantiate a PySide object without taking care of these >>>> little details, specially when people first arrive to python and PySide, as >>>> we are used to tinker with python variables as we wish.. >>>> >>>> >>>> >>>> El dom, 24 mar 2024 a las 1:03, Chris Granados- Xian (< >>>> drummanx...@gmail.com>) escribió: >>>> >>>>> When I ran into this, it has almost always been because of method >>>>> parameters initialized with default values in the constructor of some >>>>> PySide class. Let’s say class A gets instanced twice. If instance X is >>>>> garbage collected for whatever reason, when instance Y tries to use Y.b >>>>> it’ll complain about the C++ ref to 123 being lost. >>>>> >>>>> class A: >>>>> def __init__(self, a=123): >>>>> self.b=a >>>>> >>>>> >>>>> *CHRIS GRANADOS - Xian* >>>>> Pipeline TD- CG Supervisor >>>>> Bs. As., Argentina >>>>> >>>>> >>>>> On Sat, 23 Mar 2024 at 16:56 Justin Israel <justinisr...@gmail.com> >>>>> wrote: >>>>> >>>>>> Qt (C++) usually honors the parent-child relationship, so it won't >>>>>> automatically delete a widget unless its parent is being deleted. And if >>>>>> it >>>>>> doesn't have a parent, it shouldn't be automatically deleted by reference >>>>>> count unless it is wrapped in a smart pointer. Or maybe you have looked >>>>>> up >>>>>> a reference to a widget through shiboken that you didn't create, which is >>>>>> how it could later become invalid. >>>>>> Do you make use of parent-child assigments in your Python code? Does >>>>>> it happen with widgets you created in Python, or only widgets you looked >>>>>> up >>>>>> as a reference through shiboken? >>>>>> >>>>>> I think it is fair for Marcus to ask to see concrete code as an >>>>>> example, because I don't think the idea of C++ objects randomly being >>>>>> deleted from under the Python refs should be considered normal. It >>>>>> shouldn't be something you just have to expect would happen at any >>>>>> moment. >>>>>> Rather, there may be a pattern in your code that should be avoided or >>>>>> worked around. >>>>>> >>>>>> >>>>>> >>>>>> On Sun, Mar 24, 2024, 7:42 AM Juan Cristóbal Quesada < >>>>>> juan.cristobal...@gmail.com> wrote: >>>>>> >>>>>>> Hi Marcus, thanks for the reply. >>>>>>> >>>>>>> You see, that is what i want to avoid at all costs. I dont want this >>>>>>> thread conversation to evolve following a concrete, specific use case, >>>>>>> but >>>>>>> rather try to aim at "the bigger" picture. There are may examples of >>>>>>> where >>>>>>> and how this C++ already deleted error occurs. Im sure we all can think >>>>>>> of >>>>>>> one example in our code. >>>>>>> >>>>>>> My question, generally speaking, was aiming at preventing this to >>>>>>> happen at all costs by following a "good coding practice" convention. >>>>>>> For example, is it good practice to store every python widget in a >>>>>>> static class variable? would that avoid all these kinds of errors? What >>>>>>> if >>>>>>> you store a QWidget object in a python list and then try to access it >>>>>>> because it got registered as a subscriber, but, at the moment of calling >>>>>>> the method you subscribed for, the C++ bound object no longer exists >>>>>>> because the C++ reference count went to zero?? Is it good practice to >>>>>>> try >>>>>>> to use the shiboken2.isValid() method to validate everytime the C++ >>>>>>> Widget >>>>>>> pointer? all over the code? and to use the MQtUtil.findControl() method >>>>>>> to >>>>>>> retrieve a C++ alive pointer to a widget? What if we need to store a >>>>>>> widget >>>>>>> temporarily with no parent so we are able to further on perform a >>>>>>> setParent() but the C++ object was already destroyed? >>>>>>> >>>>>>> All these are use cases that we all can encounter. Im just trying to >>>>>>> figure out a general method to avoid all these problems ,specially to >>>>>>> the >>>>>>> more junior TDs, Tech Artists, etc. >>>>>>> That s why i was asking for a "general rule" to avoid these use >>>>>>> cases. Again, i would not like to make a discussion here out of a >>>>>>> specific >>>>>>> use case. But rather, mostly curious towards how the more senior >>>>>>> profiles >>>>>>> tackle with this. >>>>>>> >>>>>>> Thanks!! >>>>>>> >>>>>>> El sáb, 23 mar 2024 a las 19:07, Marcus Ottosson (< >>>>>>> konstrukt...@gmail.com>) escribió: >>>>>>> >>>>>>>> It would certainly help if you could provide an example of >>>>>>>> something that causes the error, or at the very least a stacktrace of >>>>>>>> the >>>>>>>> error. >>>>>>>> >>>>>>>> On Saturday 23 March 2024 at 18:04:59 UTC >>>>>>>> rainonthescare...@gmail.com wrote: >>>>>>>> >>>>>>>>> Hi, >>>>>>>>> i ve been working for quite some time now and >>>>>>>>> occasionally bumped into this C++ "unfamous" error. Normally, when >>>>>>>>> found >>>>>>>>> occasionally, ive been able to fix it by using the widget's >>>>>>>>> "self.findChild"/"self.findChildren" which i believe keeps the C++ >>>>>>>>> reference count of the object's pointer alive. Fair enough! >>>>>>>>> So, instead of storing the C++ widget in a python bound object, i >>>>>>>>> would retrieve it from the parent-child hierarchy, provided the >>>>>>>>> widget has >>>>>>>>> been added firstly to the layout. >>>>>>>>> >>>>>>>>> Well, we have a snippet of code in our project that relies heavily >>>>>>>>> on the publish-subscriber/observer pattern and i wouldnt like to >>>>>>>>> rewrite it >>>>>>>>> because of this C++ infernal error. So here is my question: what's >>>>>>>>> the best >>>>>>>>> policy to try to avoid this RuntimeError "forever and after"? >>>>>>>>> Ideally, i >>>>>>>>> would be tempted to use a "template" tool class that would register >>>>>>>>> all the >>>>>>>>> widgets automatically in its __init__ method and perform a >>>>>>>>> MQtUtil.findControl/MQtUtil.findLayout, but i am still encountering >>>>>>>>> this >>>>>>>>> error somewhere else..... >>>>>>>>> >>>>>>>>> I dont want to solve this punctually but rather establish a good >>>>>>>>> coding policy to avoid "forever" this!. >>>>>>>>> So, what is your policy trying to avoid this error? Have you found >>>>>>>>> a permanent solution to this? >>>>>>>>> >>>>>>>>> Thanks in advance, >>>>>>>>> My name is Juan Cristóbal Quesada >>>>>>>>> and i work as senior pipeline TD in Spain. >>>>>>>>> >>>>>>>>> Kind Regards, >>>>>>>>> JC >>>>>>>>> >>>>>>>> -- >>>>>>>> You received this message because you are subscribed to the Google >>>>>>>> Groups "Python Programming for Autodesk Maya" group. >>>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>>> send an email to python_inside_maya+unsubscr...@googlegroups.com. >>>>>>>> To view this discussion on the web visit >>>>>>>> https://groups.google.com/d/msgid/python_inside_maya/ea8d4cdc-d206-4492-bd54-d7ca3f2c5e23n%40googlegroups.com >>>>>>>> <https://groups.google.com/d/msgid/python_inside_maya/ea8d4cdc-d206-4492-bd54-d7ca3f2c5e23n%40googlegroups.com?utm_medium=email&utm_source=footer> >>>>>>>> . >>>>>>>> >>>>>>> -- >>>>>>> You received this message because you are subscribed to the Google >>>>>>> Groups "Python Programming for Autodesk Maya" group. >>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>> send an email to python_inside_maya+unsubscr...@googlegroups.com. >>>>>>> To view this discussion on the web visit >>>>>>> https://groups.google.com/d/msgid/python_inside_maya/CANOg8wX%2BfVvPD6zCcD_nhHGCxi5tnpdTdhMHzNY4VruF2VBDmQ%40mail.gmail.com >>>>>>> <https://groups.google.com/d/msgid/python_inside_maya/CANOg8wX%2BfVvPD6zCcD_nhHGCxi5tnpdTdhMHzNY4VruF2VBDmQ%40mail.gmail.com?utm_medium=email&utm_source=footer> >>>>>>> . >>>>>>> >>>>>> -- >>>>>> You received this message because you are subscribed to the Google >>>>>> Groups "Python Programming for Autodesk Maya" group. >>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>> send an email to python_inside_maya+unsubscr...@googlegroups.com. >>>>>> To view this discussion on the web visit >>>>>> https://groups.google.com/d/msgid/python_inside_maya/CAPGFgA0SK3%3DrXu2JBWMH8nQ__AjB6VnywwgFNfwj_UTePCTWEg%40mail.gmail.com >>>>>> <https://groups.google.com/d/msgid/python_inside_maya/CAPGFgA0SK3%3DrXu2JBWMH8nQ__AjB6VnywwgFNfwj_UTePCTWEg%40mail.gmail.com?utm_medium=email&utm_source=footer> >>>>>> . >>>>>> >>>>> -- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "Python Programming for Autodesk Maya" group. >>>>> To unsubscribe from this group and stop receiving emails from it, send >>>>> an email to python_inside_maya+unsubscr...@googlegroups.com. >>>>> To view this discussion on the web visit >>>>> https://groups.google.com/d/msgid/python_inside_maya/CAAgNOzSHxcBKNf39ziA7DZavEgzd4K4VQZp9y0wEi5cgOVL-Pw%40mail.gmail.com >>>>> <https://groups.google.com/d/msgid/python_inside_maya/CAAgNOzSHxcBKNf39ziA7DZavEgzd4K4VQZp9y0wEi5cgOVL-Pw%40mail.gmail.com?utm_medium=email&utm_source=footer> >>>>> . >>>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "Python Programming for Autodesk Maya" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to python_inside_maya+unsubscr...@googlegroups.com. >>>> To view this discussion on the web visit >>>> https://groups.google.com/d/msgid/python_inside_maya/CANOg8wULbvZGQdZKC7ivYEDfPM6HSVgVnydzkpUXkie5tWLRqQ%40mail.gmail.com >>>> <https://groups.google.com/d/msgid/python_inside_maya/CANOg8wULbvZGQdZKC7ivYEDfPM6HSVgVnydzkpUXkie5tWLRqQ%40mail.gmail.com?utm_medium=email&utm_source=footer> >>>> . >>>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Python Programming for Autodesk Maya" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to python_inside_maya+unsubscr...@googlegroups.com. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/python_inside_maya/CAPGFgA2tXNwhDfHU0wiFkex6_VMJfzm5y7Qb2KO-MAB5wQWoEg%40mail.gmail.com >>> <https://groups.google.com/d/msgid/python_inside_maya/CAPGFgA2tXNwhDfHU0wiFkex6_VMJfzm5y7Qb2KO-MAB5wQWoEg%40mail.gmail.com?utm_medium=email&utm_source=footer> >>> . >>> >> -- > You received this message because you are subscribed to the Google Groups > "Python Programming for Autodesk Maya" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to python_inside_maya+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/python_inside_maya/CANOg8wXAYG5cSRP9Mq8YGsYJ9p4YgmHxK4Ya%3D0qEEP3xVCLMmQ%40mail.gmail.com > <https://groups.google.com/d/msgid/python_inside_maya/CANOg8wXAYG5cSRP9Mq8YGsYJ9p4YgmHxK4Ya%3D0qEEP3xVCLMmQ%40mail.gmail.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group. To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CAPGFgA2-6C6gWoGZDJOOR5biKGCx9Rav5gsjSOdbFYrfbA0VLA%40mail.gmail.com.