I am having a rather frustrating problem using pyside and I would welcome any advice.
First, some context
I have created a simple GUI using Qt Designer and I have used pyside-uic.exe
onto my .ui
file in order to generate the associated Python file.
I am using Python 3.3 and pyside 1.2.1 with Qt Designer 4 (Qt 4.8.5).
I am using the following code to launch my GUI:
class my_dialog(QMainWindow, my_gui.Ui_main_window):
def __init__(self, parent=None):
super(my_dialog, self).__init__(parent)
self.setupUi(self)
if ("__main__" == name):
app = QApplication(sys.argv)
main_dialog = my_dialog()
# (1)
main_dialog.show()
sys.exit(app.exec_())
What I would like to achieve
My GUI features several tabs. The number of tabs is not pre-determined and is evaluated at run time. As a result, I've decided to create one tab in Qt Designer, to use as a template.
The first time I need to add a tab, I modify this template, and if I need any additionnal tab, I was planning on making a copy of that tab and then modify that copy appropriately.
The issue I have encountered
My problem is that I can't seem to find a way to copy the tab widget. After some research, I thought the copy
module (or the pickle
module, see edit) might do the trick (the following code was inserted at (1)):
new_tab = copy.deepcopy(main_dialog.my_tab)
main_dialog.my_tabs.addTab(new_tab, "")
But that triggered the following error:
main_dialog.my_tabs.addTab(new_tab, "")
RuntimeError: Internal C++ object (Pyside.QtGui.QWidget) already deleted
What I could find on my own
I have seen on SO and other sites that there may be issues, when using pyside, of objects being collected because there is no reference to them in Python.
The fact remains, however, that even if I move this code to very setupUi()
method in the .py
file generated by pyside, I still get the exact same error.
It is also worth noting that I am able to access the my_tab
object to modify its content without any trouble.
I am able to create another tab from scratch in my code and main_dialog.my_tabs.addTab(new_tab, "")
works perfectly fine in that context.
After some experimentations, I realized the problem probably occurs at the copy of the my_tab
object. Indeed, copying a tab object that I just created, I could see that trying to add the copy to the GUI tabs failed too, and with the same error.
It looks like the copy fails somehow, or the object is being immediately deleted for some reason. That's what I'm infering anyway...
My question
Considering all this, I would like to find a way to either succeed in the object copy, find another way to use an existing pyside object as template for other similar objects.
I could of course take the code for the tab out of the generated file and code my own addTab()
method. However, I am expected to build from an existing .ui
file and avoid hardcoding GUI elements.
EDIT:
When using pickle
:
new_tab = pickle.loads(pickle.dumps(main_dialog.my_tab, -1))
I get the following error:
new_tab = pickle.loads(pickle.dumps(main_dialog.my_tab, -1))
_pickle.PicklingError: Can't pickle <class 'Pyside.QtCore.SignalInstance'>: attribute lookup Pyside.QtCore.SignalInstance failed.