Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在PyQt QAbstractTableModel中编辑表,不删除内容_Python_Pyqt4_Qabstracttablemodel - Fatal编程技术网

Python 在PyQt QAbstractTableModel中编辑表,不删除内容

Python 在PyQt QAbstractTableModel中编辑表,不删除内容,python,pyqt4,qabstracttablemodel,Python,Pyqt4,Qabstracttablemodel,到目前为止我所做的: 我正在实现一个自定义的QAbstractTableModel(用于QTableView-Widget),其中包含可编辑的单元格。这些单元格的属性在myflags()方法中指定,如下所示: def flags(self, index): # Qt was imported from PyQt4.QtCore if index.column() < 2: return Qt.ItemIsEditable | Qt.ItemIsEnabled |

到目前为止我所做的:

我正在实现一个自定义的
QAbstractTableModel
(用于
QTableView
-Widget),其中包含可编辑的单元格。这些单元格的属性在my
flags()
方法中指定,如下所示:

def flags(self, index):  # Qt was imported from PyQt4.QtCore
    if index.column() < 2:
        return Qt.ItemIsEditable | Qt.ItemIsEnabled | \
               Qt.ItemIsSelectable
    else:
        return Qt.ItemIsEnabled | Qt.ItemIsSelectable
def标志(self,index):#Qt是从PyQt4.QtCore导入的
如果index.column()小于2:
返回Qt.ItemIsEditable | Qt.ItemIsEnabled |\
Qt.ItemIsSelectable
其他:
返回Qt.ItemIsEnabled | Qt.itemisselect
前两列中的单元格被标记为可编辑,就像我想要的那样

我想做什么:

但是,当双击单元格以触发编辑时,所包含的文本将被删除,并显示一个空字段

但是我不想删除和替换包含的文本,因为包含的文本可能很长,不应该重新键入。我只想编辑已经包含的内容。双击时,单元格应可编辑,其中包含以前包含的文本(可能已选中)

问题:


我如何实现这种行为?是否需要编辑我的flags方法并为这些单元格指定不同的属性?

您有几个选项

编辑期间,单元格中没有显示任何数据,因为您可能尚未为模型中的每个项目在上设置任何数据。默认情况下,
QTableWidget
会这样做

另一种方法是使用
QItemDelegate
。这将允许您手动创建编辑器小部件,并在它出现在
QTableView
中之前对其进行初始化。如果编辑文本尚未填充,则可以使用显示角色文本

class MyDelegate(QtGui.QItemDelegate):

    def createEditor(self, parent, option, index):
        if index.column() == 2:
            return super(MyDelegate, self).createEditor(parent, option, index)
        return None

    def setEditorData(self, editor, index):
        if index.column() == 2:
            # Gets display text if edit data hasn't been set.
            text = index.data(Qt.EditRole) or index.data(Qt.DisplayRole)
            editor.setText(text)         

delegate = MyDelegate()
tableview.setItemDelegate(delegate)
正如Brendan Abel所说

编辑过程中单元格中未显示任何数据,因为您可能尚未在
Qt.EditRole
上为模型中的每个项目设置任何数据

在这种情况下,要在双击单元格后在编辑框中显示以前的数据,需要以
EditRole
的方式访问
data()
,因此您应该在继承的模型类中实现
data()
方法,如下所示:

def flags(self, index):  # Qt was imported from PyQt4.QtCore
    if index.column() < 2:
        return Qt.ItemIsEditable | Qt.ItemIsEnabled | \
               Qt.ItemIsSelectable
    else:
        return Qt.ItemIsEnabled | Qt.ItemIsSelectable
def数据(self、index、role=None):
...
如果角色==QtCore.Qt.DisplayRole或角色==QtCore.Qt.EditRole:
item=index.internalPointer()
返回item.data[index.column()]
...

这也在

中提到,谢谢。我用
QItemDelegate
尝试了您的第二种方法,它的效果与预期的一样。如果我想在不使用类的情况下设置
Qt.EditRole
,我该怎么做?我需要在自定义的
表格模型中定义一个新方法吗?我认为您不需要在模型中做任何事情。不过,为什么需要创建自定义模型还是有疑问的。
QStandardItemModel
不起作用吗?如果您只想控制标志,可以在创建项目时对其进行设置。它不必是模型上的动态函数。好吧,我只是想知道如何使用PyQt做任何事情,甚至不知道有一个类似于标准类的东西。我会查一下。另外,除非你知道你需要一个模型,否则项目小部件类--
QTreeWidget
QTableWidget
,等等通常就足够了,通常编码和创建速度会更快,代码也会更简单。@user118967 Qt和PySide文档非常好,并详细介绍了其中的大部分内容。此外,如果您使用Creator或Designer下载PySide或Qt,它们会包含所有这些小部件类型的一系列示例PyQt5@Ciastopiekarz它说它返回一个指向内部数据的指针,在我的应用程序中它确实返回一个数据对象,而不是一个都没有,只要索引是有效的。我很感激关于需要包含EditRole条件的信息。然而,这个答案建议获取数据QTableView的
索引
对象。这似乎与整个模型视图概念相矛盾,即数据(模型)与视图分离。返回值可能是从模型用于存储其数据的任何自定义数据结构计算或读取的,而不一定是从index.internalPointer读取的。事实上,OP可能已经实现了
数据
这样做,只需要添加条件
role==QtCore.Qt.EditRole
@user118967谢谢你的建议。我只是简单地遵循了官方的模型视图示例。在代码中,
data(..)
(ln143)调用
getItem(..)
(ln159)最后调用
index.internalPointer()
(ln161)。在我看来,它应该是无害的,因为
索引
是由模型类中的
索引(…)
生成的模型索引对象,而不是由视图生成的。