kunek
kunek

Reputation: 91

Creating item with a integer, QStandardItem doesn't provide QSpinBox

I use PySide2 and QTableView with QStandardItemModel (object called resourcesModel) in my program. When I use the following code to create, fill and put an item into the table:

item = QStandardItem()
item.setData(123123, Qt.EditRole)
resourcesModel.setItem(1, 1, item)

when I double-click on a cell containg that value, it provides a box to edit the data, that I can put letters into. My expected behaviour is to have a QSpinBox so that only numbers can be put there.

This code:

item = QStandardItem()
item.setData(0.25, Qt.EditRole)
resourcesModel.setItem(1, 1, item)

presents a QDoubleSpinBox after double-clicking the cell, as expected. Both of these codes in PyQt5 provide the spinboxes as expected.

Why does QStandardItem doesn't provide a QSpinBox, when the value put in is just an integer? Is it possible to get around this without writing a custom delegate?

Thank you for all your answers.

Upvotes: 1

Views: 856

Answers (1)

eyllanesc
eyllanesc

Reputation: 244282

Explanation:

What happens is that PySide2 converts the integer from python to LongLong (QVariant::LongLong=4) in C++ which is not handled by the default QItemEditorFactory by default making a QLineEdit used (in PyQt is converted to QMetaType::Int=2).

Solution:

One possible solution is to create a custom QItemEditorFactory that returns the appropriate widget:

from PySide2 import QtCore, QtGui, QtWidgets


class ItemEditorFactory(QtWidgets.QItemEditorFactory):
    def createEditor(self, userType, parent):
        if userType == 4:
            return QtWidgets.QSpinBox(parent, minimum=-2147483648, maximum=2147483647)
        return super().createEditor(userType, parent)


if __name__ == "__main__":
    app = QtWidgets.QApplication([])

    factory = ItemEditorFactory()
    QtWidgets.QItemEditorFactory.setDefaultFactory(factory)

    w = QtWidgets.QTableView()

    resourcesModel = QtGui.QStandardItemModel(2, 2)
    w.setModel(resourcesModel)

    item = QtGui.QStandardItem()
    item.setData(123123, QtCore.Qt.EditRole)
    resourcesModel.setItem(1, 1, item)

    w.resize(640, 480)
    w.show()

    app.exec_()

Upvotes: 1

Related Questions