model.index() returns wrong class
-
If you run either this PyQt5 Python script:
from PyQt5.QtWidgets import QApplication from PyQt5.QtWidgets import QTreeView from PyQt5.QtCore import QModelIndex from PyQt5.QtGui import QStandardItem from PyQt5.QtGui import QStandardItemModel app = QApplication([]) treeview1 = QTreeView() model = QStandardItemModel() parentModelItem = model.invisibleRootItem() standardItem = QStandardItem('--') parentModelItem.appendRow((standardItem)) modelIndex = model.index(0, 0, QModelIndex()) print(type(modelIndex.model())) # output: <class 'PyQt5.QtGui.QStandardItemModel'>or this Pyside2 script:
from PySide2.QtWidgets import QApplication from PySide2.QtWidgets import QTreeView from PySide2.QtCore import QModelIndex from PySide2.QtGui import QStandardItem from PySide2.QtGui import QStandardItemModel app = QApplication([]) treeview1 = QTreeView() model = QStandardItemModel() parentModelItem = model.invisibleRootItem() standardItem = QStandardItem('--') parentModelItem.appendRow((standardItem)) modelIndex = model.index(0, 0, QModelIndex()) print(type(modelIndex.model())) # output: <class 'PySide2.QtGui.QStandardItemModel'>the result in both cases is that the index() function returns a
QStandardItemModelobject.However, documentation says, the result is a
QAbstractItemModelThe difference is the function signatures:
(1)
index()ofQStandardItemModelrequiresrowandcolumnonly, while
(2)index()ofQAbstractItemModelrequiresrow,columnandparent indexOnly (2) allows a unique access of items in a non-trivial QTreeView.
As there is no other way to access the current selected treeview item, this appears to be a show stopper.
Am I doing something wrong?
/////////////
Debian 10.10 Buster
PySide2 5.15.2
Python 3.7.3 -
Got it.
However, the result differs from the claimed problem in this thread:
I have a QTreeView.currenIndex() and wanted to retrieve an item from it, then obtain different data columns from this item, which led to the problem.
This is all nonsense.
With a QModelIndex, a column can easily be retrieved with:
myCurrentIndex.sibling(row, col)And that's it.
@JonB: I apologize for having made these waves and thank you for your patient assistance, which helped me find the solution :-).
-
If you run either this PyQt5 Python script:
from PyQt5.QtWidgets import QApplication from PyQt5.QtWidgets import QTreeView from PyQt5.QtCore import QModelIndex from PyQt5.QtGui import QStandardItem from PyQt5.QtGui import QStandardItemModel app = QApplication([]) treeview1 = QTreeView() model = QStandardItemModel() parentModelItem = model.invisibleRootItem() standardItem = QStandardItem('--') parentModelItem.appendRow((standardItem)) modelIndex = model.index(0, 0, QModelIndex()) print(type(modelIndex.model())) # output: <class 'PyQt5.QtGui.QStandardItemModel'>or this Pyside2 script:
from PySide2.QtWidgets import QApplication from PySide2.QtWidgets import QTreeView from PySide2.QtCore import QModelIndex from PySide2.QtGui import QStandardItem from PySide2.QtGui import QStandardItemModel app = QApplication([]) treeview1 = QTreeView() model = QStandardItemModel() parentModelItem = model.invisibleRootItem() standardItem = QStandardItem('--') parentModelItem.appendRow((standardItem)) modelIndex = model.index(0, 0, QModelIndex()) print(type(modelIndex.model())) # output: <class 'PySide2.QtGui.QStandardItemModel'>the result in both cases is that the index() function returns a
QStandardItemModelobject.However, documentation says, the result is a
QAbstractItemModelThe difference is the function signatures:
(1)
index()ofQStandardItemModelrequiresrowandcolumnonly, while
(2)index()ofQAbstractItemModelrequiresrow,columnandparent indexOnly (2) allows a unique access of items in a non-trivial QTreeView.
As there is no other way to access the current selected treeview item, this appears to be a show stopper.
Am I doing something wrong?
/////////////
Debian 10.10 Buster
PySide2 5.15.2
Python 3.7.3@nst0022
Hi and welcome.Thank you for laying out your question neatly, better than many do here :)
I can see you know what you're talking about, but I'm struggling to understand what actually goes wrong for you? The method returns a
QAbstractItemModel, and the instance is aQStandardItemModel, which inherits fromQAbstractItemModel, so what is wrong? I don't recognise your difference in function signatures,QAbstractItemModel.index()takes a parent index defaulting to none and that method is overridden byQStandardItemModelto do whatever extra processing but still with that third parameter. Pass your parent index whenever you have one. -
@nst0022
Hi and welcome.Thank you for laying out your question neatly, better than many do here :)
I can see you know what you're talking about, but I'm struggling to understand what actually goes wrong for you? The method returns a
QAbstractItemModel, and the instance is aQStandardItemModel, which inherits fromQAbstractItemModel, so what is wrong? I don't recognise your difference in function signatures,QAbstractItemModel.index()takes a parent index defaulting to none and that method is overridden byQStandardItemModelto do whatever extra processing but still with that third parameter. Pass your parent index whenever you have one.@JonB: Thanks for your quick and concise reply.
@JonB said in model.index() returns wrong class:
Pass your parent index whenever you have one.
That does not work, I already did that and extended my example above:
from PySide2.QtWidgets import QApplication from PySide2.QtWidgets import QTreeView from PySide2.QtCore import QModelIndex from PySide2.QtGui import QStandardItem from PySide2.QtGui import QStandardItemModel app = QApplication([]) treeview1 = QTreeView() model = QStandardItemModel() parentModelItem = model.invisibleRootItem() standardItem = QStandardItem('--') parentModelItem.appendRow((standardItem)) modelIndex = model.index(0, 0, QModelIndex()) #new: modelIndexParent = modelIndex.parent() item = modelIndex.model().item(0, 0, modelIndexParent)The result is:
python3 bug_1_pyside2_b.py Traceback (most recent call last): File "bug_1_pyside2_b.py", line 18, in <module> item = modelIndex.model().item(0, 0, modelIndexParent) TypeError: PySide2.QtGui.QStandardItemModel.item(): too many argumentsthis error message is contrary to:
@JonB said in model.index() returns wrong class:
is overridden by QStandardItemModel ... but still with that third parameter
I guess the third parameter is inadvertently omitted in the implementation of QStandardItemModel.
-
@JonB: Thanks for your quick and concise reply.
@JonB said in model.index() returns wrong class:
Pass your parent index whenever you have one.
That does not work, I already did that and extended my example above:
from PySide2.QtWidgets import QApplication from PySide2.QtWidgets import QTreeView from PySide2.QtCore import QModelIndex from PySide2.QtGui import QStandardItem from PySide2.QtGui import QStandardItemModel app = QApplication([]) treeview1 = QTreeView() model = QStandardItemModel() parentModelItem = model.invisibleRootItem() standardItem = QStandardItem('--') parentModelItem.appendRow((standardItem)) modelIndex = model.index(0, 0, QModelIndex()) #new: modelIndexParent = modelIndex.parent() item = modelIndex.model().item(0, 0, modelIndexParent)The result is:
python3 bug_1_pyside2_b.py Traceback (most recent call last): File "bug_1_pyside2_b.py", line 18, in <module> item = modelIndex.model().item(0, 0, modelIndexParent) TypeError: PySide2.QtGui.QStandardItemModel.item(): too many argumentsthis error message is contrary to:
@JonB said in model.index() returns wrong class:
is overridden by QStandardItemModel ... but still with that third parameter
I guess the third parameter is inadvertently omitted in the implementation of QStandardItemModel.
@nst0022 said in model.index() returns wrong class:
I guess the third parameter is inadvertently omitted in the implementation of QStandardItemModel.
Let's at least start from the C++ documentation for Qt:
QModelIndex QAbstractItemModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const
This is marked[pure virtual], which means it has no implementation inQAbstractItemModeland must be overridden in inheritors.QModelIndex QStandardItemModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const
This is marked[override virtual]. And documented:Reimplements:
QAbstractItemModel::index(int row, int column, const QModelIndex &parent) const.QStandardItemModeldoes not offer any other definition forindex().Now I'm getting lost. You originally were asking about
index()method. You now show an error messageitem = modelIndex.model().item(0, 0, modelIndexParent) TypeError: PySide2.QtGui.QStandardItemModel.item(): too many argumentsThat is
item()method.QAbstractItemModeldoes not have anyitem()method to override, andQStandardItemModelhas just item(int row, int column = 0) which is indeed 2 not 3 arguments.Before I look any further, could you clarify which method you are finding at fault?
BTW, if you are wanting a tree model from a
QStandardItemModelthen https://doc.qt.io/qt-5/qstandarditemmodel.html#details gives some sample code. Note it includes:Since a QAbstractItemView provides QModelIndex-based signals and functions, you need a way to obtain the QStandardItem that corresponds to a given QModelIndex, and vice versa. itemFromIndex() and indexFromItem() provide this mapping.
QStandardItem *item = myStandardItemModel->itemFromIndex(index); -
@nst0022 said in model.index() returns wrong class:
I guess the third parameter is inadvertently omitted in the implementation of QStandardItemModel.
Let's at least start from the C++ documentation for Qt:
QModelIndex QAbstractItemModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const
This is marked[pure virtual], which means it has no implementation inQAbstractItemModeland must be overridden in inheritors.QModelIndex QStandardItemModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const
This is marked[override virtual]. And documented:Reimplements:
QAbstractItemModel::index(int row, int column, const QModelIndex &parent) const.QStandardItemModeldoes not offer any other definition forindex().Now I'm getting lost. You originally were asking about
index()method. You now show an error messageitem = modelIndex.model().item(0, 0, modelIndexParent) TypeError: PySide2.QtGui.QStandardItemModel.item(): too many argumentsThat is
item()method.QAbstractItemModeldoes not have anyitem()method to override, andQStandardItemModelhas just item(int row, int column = 0) which is indeed 2 not 3 arguments.Before I look any further, could you clarify which method you are finding at fault?
BTW, if you are wanting a tree model from a
QStandardItemModelthen https://doc.qt.io/qt-5/qstandarditemmodel.html#details gives some sample code. Note it includes:Since a QAbstractItemView provides QModelIndex-based signals and functions, you need a way to obtain the QStandardItem that corresponds to a given QModelIndex, and vice versa. itemFromIndex() and indexFromItem() provide this mapping.
QStandardItem *item = myStandardItemModel->itemFromIndex(index); -
@JonB You are right, I confused
item()andindex()Now I am totally at lost.
I have to thoroughly revisit the subject.@nst0022
Indeed :)I think that last "BTW" of mine might be what you are looking for in a hierarchical tree model: QStandardItem *QStandardItemModel::itemFromIndex(const QModelIndex &index) const.
I am unsure how QStandardItem *QStandardItemModel::item(int row, int column = 0) const treats
rowin a hierarchical model, you would have to play with that to compare againstitemFromIndex()which accepts aQModelIndex. -
Got it.
However, the result differs from the claimed problem in this thread:
I have a QTreeView.currenIndex() and wanted to retrieve an item from it, then obtain different data columns from this item, which led to the problem.
This is all nonsense.
With a QModelIndex, a column can easily be retrieved with:
myCurrentIndex.sibling(row, col)And that's it.
@JonB: I apologize for having made these waves and thank you for your patient assistance, which helped me find the solution :-).
-
Got it.
However, the result differs from the claimed problem in this thread:
I have a QTreeView.currenIndex() and wanted to retrieve an item from it, then obtain different data columns from this item, which led to the problem.
This is all nonsense.
With a QModelIndex, a column can easily be retrieved with:
myCurrentIndex.sibling(row, col)And that's it.
@JonB: I apologize for having made these waves and thank you for your patient assistance, which helped me find the solution :-).
-
I have now figured out, why I had trouble with the item() and index() functions.
If you look-up code on the Internet, both C and Python examples exist, where a model has an index() function.
However, the Python documentation of
QStandardItemModeldoes not mention index() in its function list, where the corresponding C documentation does (in Reimplemented Public Functions), but the function can be used in Python anyway.I assume, that it does not make sense to report this kind of Python documentation errors, as long as the examples still contain C code.
-
I have now figured out, why I had trouble with the item() and index() functions.
If you look-up code on the Internet, both C and Python examples exist, where a model has an index() function.
However, the Python documentation of
QStandardItemModeldoes not mention index() in its function list, where the corresponding C documentation does (in Reimplemented Public Functions), but the function can be used in Python anyway.I assume, that it does not make sense to report this kind of Python documentation errors, as long as the examples still contain C code.
@nst0022
When I first did Qt I was Python. That was PyQt5. PySide2 didn't exist yet, and that documentation you refer to is for PySide2. There isn't an equivalent for PyQt5. The PySide2 stuff largely holds.So PyQt5 made you look up the C++ Qt documentation anyway. My advice would be you should combine that C++ look up with the PySide2. The PySide2 is mostly some kind of "copy" from the C++. It may have omissions. Anyway, there's my tip, use the C++ as well at least.
-
@nst0022
When I first did Qt I was Python. That was PyQt5. PySide2 didn't exist yet, and that documentation you refer to is for PySide2. There isn't an equivalent for PyQt5. The PySide2 stuff largely holds.So PyQt5 made you look up the C++ Qt documentation anyway. My advice would be you should combine that C++ look up with the PySide2. The PySide2 is mostly some kind of "copy" from the C++. It may have omissions. Anyway, there's my tip, use the C++ as well at least.