Ошибка при выполнении делегата QDoubleSpinBox в QTableView

В таблице QTableView при вводе значения в ячейку, делегат QDoubleSpinBox выполняется с ошибкой :

in setEditorData editor.setValue(float(value))
TypeError: float() argument must be a string or a number, not 'NoneType

Поскольку ошибка в методе setEditorData, я пробовал вносить изменения :

editor.setValue(float(value))
editor.setValue(int(value))
editor.setValue(value)

но ошибка не исчезает.

Что нужно исправить?

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QStyledItemDelegate, QDoubleSpinBox
from PyQt5.QtCore import Qt

class SpinDelegate(QStyledItemDelegate):
    signal_delegate = QtCore.pyqtSignal(int, int) 

    def createEditor(self, parent, options, index):
        editor = QDoubleSpinBox(parent)
        editor.valueChanged.connect(
            lambda val, row=index.row(): self.update_editor(val, row))
        editor.setSingleStep(0.1)
        editor.setDecimals(2)
    
        return editor

    def setEditorData(self, editor, index):
        value = index.model().data(index, Qt.EditRole)
        editor.setValue(float(value))

        #  editor.setValue(int(value))
        #  editor.setValue(str(value))
        #  editor.setValue(value)

    def updateEditorGeometry(self, editor, options, index):
        editor.setGeometry(options.rect)

    def setModelData(self, editor, model, index):
        value = str(editor.value())
        model.setData(index, value[0:4], Qt.EditRole)

    def update_editor(self, val, row):
        self.signal_delegate.emit(val, row)

app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QWidget()
window.setWindowTitle("Класс QTableView")
window.resize(500, 400)
view = QtWidgets.QTableView()

model = QtGui.QStandardItemModel(10, 1)
view.setModel(model)

delegate = SpinDelegate()
view.setItemDelegateForColumn(0, delegate)

box = QtWidgets.QVBoxLayout()
box.addWidget(view)
window.setLayout(box)
window.show()
sys.exit(app.exec_())

Ответы (1 шт):

Автор решения: S. Nick

Вы можете добавить в метод setEditorData проверку:

def setEditorData(self, editor, index):
    value = index.model().data(index, Qt.EditRole)
    if not value:                                           # +++                                 
        value = 0                                           # +++
    editor.setValue(float(value))

Но вы, как по мне, можете оставить только метод createEditor и все.

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qt import QStyledItemDelegate, QDoubleSpinBox
from PyQt5.Qt import *


class SpinDelegate(QStyledItemDelegate):
#    signal_delegate = QtCore.pyqtSignal(int, int) 

    def createEditor(self, parent, options, index):
        editor = QDoubleSpinBox(parent)
#        editor.valueChanged.connect(
#            lambda val, row=index.row(): self.update_editor(val, row))
        editor.setSingleStep(0.1)
        editor.setDecimals(2)
        return editor

'''
    def setEditorData(self, editor, index):
        value = index.model().data(index, Qt.EditRole)
        if not value:                                           # +++                                 
            value = 0                                           # +++
        editor.setValue(float(value))

        #  editor.setValue(int(value))
        #  editor.setValue(str(value))
        #  editor.setValue(value)

    def updateEditorGeometry(self, editor, options, index):
        editor.setGeometry(options.rect)

    def setModelData(self, editor, model, index):
        value = str(editor.value())
        model.setData(index, value[0:4], Qt.EditRole)

    def update_editor(self, val, row):
        self.signal_delegate.emit(val, row)
'''


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.tableView = QtWidgets.QTableView()        
        self.model = QtGui.QStandardItemModel(10, 1)
        self.tableView.setModel(self.model)        
        
        delegate = SpinDelegate(self.tableView)                  # +++ self.tableView
        self.tableView.setItemDelegateForColumn(0, delegate)

        box = QtWidgets.QVBoxLayout(self)
        box.addWidget(self.tableView)
        

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MainWindow()
    w.setWindowTitle("Класс QTableView")
    w.resize(500, 400)
    w.show()
    sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка