PySide QTableView setData 用于多个单元格
Posted
技术标签:
【中文标题】PySide QTableView setData 用于多个单元格【英文标题】:PySide QTableView setData for multiple cells 【发布时间】:2016-11-24 09:08:48 【问题描述】:我正在使用 QTableView
并子分类为 QAbstractTableModel
。编辑单元格时,我注意到QAbstractTableModel.setData
只通过最后一个选定的单元格。有没有办法让setData
处理多个(选定的)单元格?
作为使用示例:
从表格中选择四个单元格。 开始编辑一个单元格。 输入一个值并按回车键提交。 让值修改所有四个单元格(目前它只修改最后选择的单元格)我尝试对closeEditor
进行子类化,然后循环通过selectedIndexes
以使用setData
调用它们,但我不知道如何从closeEditor
获取用户的输入值。
这是我的尝试,差不多了,只需要输入值。
def closeEditor(self, editor, hint):
is_cancelled = (hint == QtGui.QAbstractItemDelegate.RevertModelCache)
if not is_cancelled:
for index in self.selectedIndexes():
if index == self.currentIndex():
continue
input_value = ??? # Don't know how to get this from here!
self.model().setData(index, input_value, QtCore.Qt.EditRole)
return QtGui.QTableWidget.closeEditor(self, editor, hint)
【问题讨论】:
【参考方案1】:closeEditor
信号中的editor
是用于编辑的小部件。
如果是,例如QLineEdit
,您可以通过其text
属性读取它的文本。
获取属性值的一种方法是通过 QObject 的属性 API
value = editor.property("text")
【讨论】:
编辑器是QWidget
,所以没有text属性。
正如我所写:如果小部件是QLineEdit
,那么它有一个文本属性。 IE。这取决于哪个小部件被用作编辑器。默认委托对文本使用行编辑,对数字使用旋转框等
那它使用哪一个呢? editor
的类名是什么? IE。 editor.metaObject().className()
的值?
editor.metaObject().className()
是 QExpandingLineEdit
。虽然type(editor)
是QWidget
,所以我不能像你建议的那样只打电话给editor.text
,因为它不存在。 editor().metaObject()
中的值是否填充在某处?我检查了它的文档,但真的找不到方法。
@GreenCell。这里给出的答案在技术上是正确的。 QExpandingLineEdit
是一个内部 Qt 类,它是 QLineEdit
的子类。 PySide 中似乎有一个错误,因为它应该将QLineEdit
的实例传递给closeEditor
,而不是QWidget
。相同的代码在 PyQt4 中可以正常工作(即它传递了一个QLineEdit
)。【参考方案2】:
编辑:我将其用作解决方法,因为 PySide 中有一个错误,其中 editor
仅返回 QWidget
。请看 Kevin Krammer 的回答!
虽然这是一个小问题,但到目前为止我的解决方案似乎运行良好。请告诉我是否有更好的方法,这有点啰嗦。
在closeEditor
中,我让每个单元格都通过setData
,并以None
作为值。
然后在QAbstractTableModel
我有一个变量_input_value
将存储用户的输入以供其余单元格抓取。
class TableView(QtGui.QTableView):
def __init__(self, parent=None):
super(TableView, self).__init__(parent)
def closeEditor(self, editor, hint):
is_cancelled = (hint == QtGui.QAbstractItemDelegate.RevertModelCache)
if not is_cancelled:
for index in self.selectedIndexes():
if index == self.currentIndex():
continue
# Supply None as the value
self.model().setData(index, None, QtCore.Qt.EditRole)
# Reset value for next input
if self.model()._input_value is not None:
self.model()._input_value = None
return QtGui.QTableWidget.closeEditor(self, editor, hint)
class TableModel(QtCore.QAbstractTableModel):
def __init__(self, parent=None):
super(TableModel, self).__init__(parent)
self.main_widget = parent
self._input_value = None
def setData(self, index, value, role):
# Triggers if user cancelled input
if value is None and self._input_value is None:
return False
if self._input_value is None:
# The last selected cell will pass through here to store the value.
self._input_value = value
else:
# All other cells will pass None, so just grab our stored value.
value = self._input_value
# Do whatever you want with value now
return True
【讨论】:
以上是关于PySide QTableView setData 用于多个单元格的主要内容,如果未能解决你的问题,请参考以下文章
不允许在 pyside 的 QTableView 中复制/粘贴
PySide + SQLAlchemy 中 QTableView 的“模型”设计
如何使用 pyside 在 QtableView 单元格中设置数据