Ошибка при выполнении делегата 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_())
