Pyside "RuntimeError: Internal C++ object (PySide2.QtWidgets.QCommonStyle) already deleted." error.

Pyside "RuntimeError: Internal C++ object (PySide2.QtWidgets.QCommonStyle) already deleted." error.

deven.saxenaP7BD5
Enthusiast Enthusiast
4,597 Views
13 Replies
Message 1 of 14

Pyside "RuntimeError: Internal C++ object (PySide2.QtWidgets.QCommonStyle) already deleted." error.

deven.saxenaP7BD5
Enthusiast
Enthusiast

Hello,

 

3Ds Max newbie here. I have a fully functional PySide tool in Maya that I am trying to make a 3ds Max version for.

Managed to get most of it working but I am getting stuck with this C++ error that I suspect is related to C++ object not getting garbage collected properly.

 

In my tool, I have a loop of QPushButtons that gets created dynamically within python. Think of it as an image/thumbnail viewer that I have connected to a database. I am using a custom Flow Layout to create a grid layout that expands and contracts based on the UI width/height. The database is tasked to do the page numbers. 

 

The problem is when I am trying to delete the page 1 layout in order to load page 2, I get this error:

"RuntimeError: Internal C++ object (PySide2.QtWidgets.QCommonStyle) already deleted."

 

This is the delete function that I am using to clear out the old layout.

def clearLayout(self, layout): 
        if layout is not None:
            while layout.count():
                item = layout.takeAt(0)
                widget = item.widget()
                if widget is not None:
                    widget.setParent(None)
                    widget.deleteLater()
                    widget.update()
                else:
                    self.clearLayout(item.layout())

 

Tried looking online for any hints and it looks like it's the deleteLater() method that might be the culprit here. Python is garbage collecting properly but somehow C++ objects are still present.

 

Using Max 2022(version 24.0 - 24.0.0.923) on the Windows platform.

 

Thanks in advance 🙂

 

 

 

 

0 Likes
Accepted solutions (1)
4,598 Views
13 Replies
Replies (13)
Message 2 of 14

denisT.MaxDoctor
Advisor
Advisor

I'm not sure that you're clearing the layout correctly... but first, why do you even need it?

0 Likes
Message 3 of 14

deven.saxenaP7BD5
Enthusiast
Enthusiast

I need to clear the layout so that I can load data from page 2. 

So the first set of images/thumbnails gets loaded and is stored as page 1. Once the user clicks on page 2, the layout dumps the widget and its children and loads page 2 creating the corresponding widgets and its children again. similarly, if a user clicks page 3, then the layout dumps the current widget and all its children and loads the contents of page 3. 

 

 

Hope this help. 

This all works seamlessly in maya. But for some reason, it is erroring out in max. 

 

 

 

0 Likes
Message 4 of 14

denisT.MaxDoctor
Advisor
Advisor

I don't understand why you need to delete widgets from page 1 when you go to page 2. You never go back to page 1?

 

0 Likes
Message 5 of 14

deven.saxenaP7BD5
Enthusiast
Enthusiast

This is to delete/unload old content from page1 and load new content for the page2. If the user decides to go to the previous page, they will click on the page1 text icon, and the current page content which is currently showing page2 contents will delete/unload from memory and page 1 contents will be loaded. 

 

So in short, we are sort of mimicking StackedWidget-like behavior but without loading all the images into memory.

0 Likes
Message 6 of 14

denisT.MaxDoctor
Advisor
Advisor

well ... I still don't understand why create and then delete a widget if you only need to change the picture.

ok, it's up to you...

but if you use takeAt, then it automatically removes the parent from the item. That is, setParent(None) is no longer needed.
deleteLater() is needed, but update() is not. You can forget about this widget after call deleteLater.

0 Likes
Message 7 of 14

denisT.MaxDoctor
Advisor
Advisor

Also, if the item for deletion has a layout with some other items (widgets) that you also want to delete, you first need to clean that layout and then delete the item itself.

0 Likes
Message 8 of 14

denisT.MaxDoctor
Advisor
Advisor

however, from my point of view, there is no point in deleting "sub"-items from the item's layout. All child elements (items, widgets, layouts) must be destructed by the system when the parent is deleted.

 

I would do something like:

 

 

 

def clearLayout(self, widget): 
	layout = widget.layout()
	if layout is not None:
		while layout.count():
			item = layout.takeAt(0)
			if item.widget():
				item.widget().deleteLater()

 

 

 

0 Likes
Message 9 of 14

deven.saxenaP7BD5
Enthusiast
Enthusiast

Thanks for looking into this Denis. I apologize if I am not clear. I will do my best in order to explain this better 🙂

 

Let me go through my setup in detail just so that you get some context. I have my Ui made in PySide. I have the thumbnail display widget(Marked in Red) that houses a vertical scroll area and has a grid layout(I am using custom Flow Layout here) as its child that displays all the thumbnails. Thumbnails are a loop of QPushButtons that gets created dynamically based on data coming from the database.

Page numbers are marked in green here. 

Currently in the image page1 contents are displayed. When the user clicks on "next page", flow_layout(currently displaying page1 contents) gets deleted and a new flow_layout with page2 contents is created. This is where I am getting that c++ error. 

 

It looks like there are some contents that are still present in the scene and as a result, the tool is erroring out. 

 

I have written this tool in Maya and it works seamlessly in Maya. 

 

P.S. I should also mention that the above shared code was me trying different methods that I found on the web to delete a layout.

Sharing my original code here:

def clearLayout(self, layout): 
        if layout is not None:
            while layout.count():
                item = layout.takeAt(0)
                widget = item.widget()
                if widget is not None:
                    widget.deleteLater()
                else:
                    self.clearLayout(item.layout())

 

0 Likes
Message 10 of 14

denisT.MaxDoctor
Advisor
Advisor

then it's easier to just delete the whole layout and create a new one for each page...

 

but your UI solution still confuses me... why pages and scroll area at the same time? It should be something one, unless the pages differ in subject (for example, the type of material: wood, concrete, glass, etc.).

0 Likes
Message 11 of 14

denisT.MaxDoctor
Advisor
Advisor

Why delete the whole item (widget)? After all, this is a complex interface element with its behavior - slots, signals, events... just change the picture (title, tooltip).

0 Likes
Message 12 of 14

deven.saxenaP7BD5
Enthusiast
Enthusiast

hmm, haven't looked into that but it sounds less complicated. But that will require a redesign on the Maya side as well. This tool has a LOT of sub functions and all of them are working in Max but this one. So would really like to get this working.

 

For your earlier question:

We have multiple pages for one material type(wood in this case) and loading all at once will be memory intensive, so,  from the database, we receive packets of 20 materials per page that we display the thumbnails for, and then if a user wants more materials, they click on "next" and packet/page2's contents are displayed. 

 

The issue is that Maya seems to be deleting the entire layout and its children so when a new layout is created, there are no clashes and the tool runs fine. But in Max, for some reason, I am getting "RuntimeError: Internal C++ object (PySide2.QtWidgets.QCommonStyle) already deleted." error.

 

 

 

 

0 Likes
Message 13 of 14

deven.saxenaP7BD5
Enthusiast
Enthusiast

Appreciate you looking into this Denis, I'll keep digging. Will update you in case I managed to find the culprit.

0 Likes
Message 14 of 14

deven.saxenaP7BD5
Enthusiast
Enthusiast
Accepted solution

For records:

 

I found the culprit. I'll try and explain what I was doing wrong. I was duplicating a dummy object and from the looks of it, Maya seems to be smart enough to rename clashing object/element names and looks like Max has a different approach to this problem, and it's easy to have multiple objects/elements in the scene sharing a common name.

 

So, I have a grid layout that has 20 QPushButtons and if my content is less than 20, say 18, I have a dummy entry that I create in order to complete the layout requirements(so in this case 2 dummy entries will be created). This dummy object is what was getting duplicated and since all the dummy entries have the same name, Max was erroring out and as a result "deleteLater()" was never getting executed.

 

I know this is hard to replicate since it is so specific to my setup but I can explain it better if anyone is facing a similar issue and needs more info.

 

 

0 Likes