gpt4 book ai didi

python - PyQt - 如何使用 QItemDelegate 在表格 View 中设置 QComboBox

转载 作者:太空狗 更新时间:2023-10-29 19:34:12 28 4
gpt4 key购买 nike

我试图在我的表格中显示一个组合框,以便我可以从表格模型中设置选定的索引,就像表格中的其他单元格一样。我已经从其他示例中将其拼凑在一起,但仍然无法理解交互如何设置 QComboBox 的选定索引。

这是我能想出的最简单的例子来说明问题。如果有人可以演示如何从模型数据自动设置索引?另外如何使用“currentIndexChanged”信号,因为它似乎在重新绘制时几乎连续触发?谢谢。

# The following tells SIP (the system that binds Qt's C++ to Python)
# to return Python native types rather than QString and QVariant
import sip
sip.setapi('QString', 2)
sip.setapi('QVariant', 2)


from PyQt4 import QtCore, QtGui

class TableModel(QtCore.QAbstractTableModel):
"""
A simple 5x4 table model to demonstrate the delegates
"""
def rowCount(self, parent=QtCore.QModelIndex()): return 5
def columnCount(self, parent=QtCore.QModelIndex()): return 4

def data(self, index, role=QtCore.Qt.DisplayRole):
if not index.isValid(): return None
if not role==QtCore.Qt.DisplayRole: return None
return "{0:02d}".format(index.row())


class ComboDelegate(QtGui.QItemDelegate):
"""
A delegate that places a fully functioning QComboBox in every
cell of the column to which it's applied
"""
def __init__(self, parent):

QtGui.QItemDelegate.__init__(self, parent)

def paint(self, painter, option, index):

self.combo = QtGui.QComboBox(self.parent())
self.connect(self.combo, QtCore.SIGNAL("currentIndexChanged(int)"), self.parent().currentIndexChanged)

li = []
li.append("Zero")
li.append("One")
li.append("Two")
li.append("Three")
li.append("Four")
li.append("Five")

self.combo.addItems(li)

if not self.parent().indexWidget(index):
self.parent().setIndexWidget(
index,
self.combo
)

class TableView(QtGui.QTableView):
"""
A simple table to demonstrate the QComboBox delegate.
"""
def __init__(self, *args, **kwargs):
QtGui.QTableView.__init__(self, *args, **kwargs)

# Set the delegate for column 0 of our table
# self.setItemDelegateForColumn(0, ButtonDelegate(self))
self.setItemDelegateForColumn(0, ComboDelegate(self))

@QtCore.pyqtSlot()
def currentIndexChanged(self, ind):
print "Combo Index changed {0} {1} : {2}".format(ind, self.sender().currentIndex(), self.sender().currentText())

if __name__=="__main__":
from sys import argv, exit

class Widget(QtGui.QWidget):
"""
A simple test widget to contain and own the model and table.
"""
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)

l=QtGui.QVBoxLayout(self)
self._tm=TableModel(self)
self._tv=TableView(self)
self._tv.setModel(self._tm)
l.addWidget(self._tv)

a=QtGui.QApplication(argv)
w=Widget()
w.show()
w.raise_()
exit(a.exec_())

最佳答案

您错误地使用了 paint 方法。当你想改变 View 的显示行为时应该使用它。每次你想要绘制它时创建新的小部件也非常昂贵。但是你想改变编辑行为,所以你需要改变你程序的整个逻辑。

参见 fixed code .下面我将解释这些变化。

1. 首先,我们需要使第一列可编辑。您可以通过重新实现 QAbstractItemModel::flags 来实现:

def flags(self, index):
if (index.column() == 0):
return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled
else:
return QtCore.Qt.ItemIsEnabled

2. 默认情况下,项目编辑器是在用户双击项目时创建的。如果你想默认显示所有组合框,你可以使用openPersistentEditor:

for row in range(0, self._tm.rowCount()):
self._tv.openPersistentEditor(self._tm.index(row, 0))

请注意,您还应该为新创建的单元格(如果有)打开编辑器。

3. 现在回到我们的委托(delegate)。我们需要实现 createEditor 方法,当为单元格请求编辑器时, View 将自动调用该方法:

def createEditor(self, parent, option, index):
combo = QtGui.QComboBox(parent)
li = []
li.append("Zero")
li.append("One")
li.append("Two")
li.append("Three")
li.append("Four")
li.append("Five")
combo.addItems(li)
self.connect(combo, QtCore.SIGNAL("currentIndexChanged(int)"),
self, QtCore.SLOT("currentIndexChanged()"))
return combo

请注意 connect 位于 append 之下,因为我们需要避免在初始化时发出 currentIndexChanged 信号。

4. 实现 setEditorData 方法,当模型数据发生变化时 View 将调用该方法。编辑器初始化时也会调用一次。

def setEditorData(self, editor, index):
editor.blockSignals(True)
editor.setCurrentIndex(int(index.model().data(index)))
editor.blockSignals(False)

同样,我们希望避免非用户引起的信号,因此我们使用 blockSignals

5. 在插槽中,我们简单地发出 commitData 信号,这将导致 View 调用我们委托(delegate)的 setModelData:

@QtCore.pyqtSlot()
def currentIndexChanged(self):
self.commitData.emit(self.sender())

6. 实现setModelData方法:

def setModelData(self, editor, model, index):
model.setData(index, editor.currentIndex())

7. 您的模型需要支持数据更改。所以我们应该实现模型的setData方法:

def setData(self, index, value, role=QtCore.Qt.DisplayRole):
print "setData", index.row(), index.column(), value
# todo: remember the data

关于python - PyQt - 如何使用 QItemDelegate 在表格 View 中设置 QComboBox,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17615997/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com