Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are default arguments handled in pyqt?

Tags:

python

qt

pyqt

In Qt, you have this routine (among others) in QAbstractItemModel

bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());

Which basically instantiates a new QModelIndex every time it is called if parent is not specified.

In python, the meaning of the same line is vastly different: only one QModelIndex would be instantiated and shared at every call

The point that is not clear to me is how this difference is handled in PyQt. The documentation seems to be automatically generated from the C++ one, with the result that the default argument instantiation uses the same syntax, but with a completely different meaning, leaving the issue unaddressed.

This problem of course carries on to custom reimplementations in PyQt of the QAbstractItemModel. Should you declare

 def insertRows(self, row, count, index=QtCore.QModelIndex()): 

or

 def insertRows(self, row, count, index=None): 

and then instantiate a new QModelIndex if index is None?

like image 901
Stefano Borini Avatar asked Dec 29 '25 11:12

Stefano Borini


1 Answers

bool insertRows(int row, int count, 
                const QModelIndex &parent = QModelIndex());

and

def insertRows(self, row, count, index=QtCore.QModelIndex()): 

Both of these examples result in invalid index instance.

What is an invalid QModelIndex?

An invalid model index can be constructed with the QModelIndex constructor. Invalid indexes are often used as parent indexes when referring to top-level items in a model.

Does insertRows need a new invalid instance each time it is called?

In case of the insertRows function the base class implementation of this function does nothing and returns false.

The quote means that if you use QAbstractItemModel you need to implement insertRows yourself. This means you need to call beginInsertRows which takes the parent argument.

When parent indexes are involved, C++ side of Qt will not care which instance is given. As long as it is invalid it will mean the current item is in the top level of the model and has no parent.

QAbstractItemModel should not delete any indexes that it hasn't created by it self. In C++, the parent argument is passed as const reference and thus will not be deleted or changed by beginInsertRows function.

Segmentation faults that could occur if C++ instance was deleted while it was still referenced in Python are your biggest problem I think.

Now in Python, the argument created in function definition will usually have long life span, and there could be ways for the instance to get deleted that I am unaware of but generally you should be safe.

If you are worried about this simply create new instance each time.

index = index or QtCore.QModelIndex()

But for what it's worth I don't remember having trouble creating index instances in function definitions and I have done so in several occasions.

like image 67
Davor Lucic Avatar answered Dec 31 '25 01:12

Davor Lucic