使用 QStyledItemDelegate 验证 QTreeWidget 的特定列无法正常工作
Posted
技术标签:
【中文标题】使用 QStyledItemDelegate 验证 QTreeWidget 的特定列无法正常工作【英文标题】:validating specific column of QTreeWidget using QStyledItemDelegate not working properly 【发布时间】:2021-05-16 17:06:55 【问题描述】:我有一个 3 列的 QTreeWidget,只有第 3 列应该有一个双重验证器。我的问题是它有点工作。 QLineEdit 不会在 100 处停止,它会继续前进。
我错过了什么;让它在不让用户输入高于 100 的任何内容的情况下仍然编辑 lineEdit?
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class Delegate(QStyledItemDelegate):
'Changes number of decimal places in gas analysis self.chosen table'
def __init__(self, decimals, parent=None):
super().__init__(parent)
self.nDecimals = decimals
def createEditor(self, parent, option, index):
editor = QLineEdit(parent)
editor.setValidator(QDoubleValidator(0,100, 15))
return editor
def setEditorData(self, editor, index):
if index.column() == 2 and index.data() is not None:
editor.setText(str(float(index.data())))
class Widget(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self, parent=None)
self.tree_widget = QTreeWidget()
self.tree_widget.setItemDelegate(Delegate(self.tree_widget))
self.tree_widget.setHeaderLabels(["Value1", "Value2", "Value3"])
self.setCentralWidget(self.tree_widget)
for vals in [("h", "20.0", "40.0"), ("k", "25.0", "50.0")]:
it = QTreeWidgetItem(vals)
it.setFlags(it.flags()| Qt.ItemIsEditable)
self.tree_widget.addTopLevelItem(it)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
【问题讨论】:
首先,实现是不够的,因为它没有正确覆盖其他列,并且您正在创建的实例的参数与__init__
的签名不匹配。但是,最重要的是,为什么要使用 QLineEdit 而不是 QDoubleSpinBox?
【参考方案1】:
QDoubleValidator 仅尝试验证用户输入的文本,如果不符合要求,则不会保存信息,这就是您的情况所观察到的。如果您想定义您希望用户在特定情况下使用哪些值,最好使用 QDoubleSpinBox 作为编辑器:
class Delegate(QStyledItemDelegate):
def __init__(self, decimals, parent=None):
super().__init__(parent)
self.nDecimals = decimals
def createEditor(self, parent, option, index):
editor = QDoubleSpinBox(
parent, minimum=0, maximum=100.0, decimals=self.nDecimals
)
return editor
def setEditorData(self, editor, index):
if index.data() is not None:
try:
value = float(index.data())
except Exception as e:
print("error", e)
else:
editor.setValue(value)
class Widget(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self, parent=None)
self.tree_widget = QTreeWidget()
self.tree_widget.setHeaderLabels(["Value1", "Value2", "Value3"])
self.tree_widget.setItemDelegateForColumn(2, Delegate(15, self.tree_widget))
self.setCentralWidget(self.tree_widget)
for vals in [("h", "20.0", "40.0"), ("k", "25.0", "50.0")]:
it = QTreeWidgetItem(vals)
it.setFlags(it.flags() | Qt.ItemIsEditable)
self.tree_widget.addTopLevelItem(it)
注意:我已经修改了列选择,因为在 OP 的初始实现中,所有列都使用相同的编辑器,这显然与其相同的要求相矛盾,所以不要使用 setItemDelegate()我用过 setItemDelegateForColumn()。
【讨论】:
以上是关于使用 QStyledItemDelegate 验证 QTreeWidget 的特定列无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 QStyledItemDelegate 在 QTreeWidget 中拥有不同高度的 QTreeWidgetItems?
Qt表格中的自定义编辑组件---------------自定义代理QStyledItemDelegate
QListView 与 CustomWIdget 使用 QStyledItemDelegate
在带有 QSqlQueryModel 的 QListView 上使用 QStyledItemDelegate