gpt4 book ai didi

python - 如何恢复 QTableView 中 QComboBox 委托(delegate)的索引?

转载 作者:行者123 更新时间:2023-11-30 21:49:50 26 4
gpt4 key购买 nike

有一个QTableView(),其中一列填充有QComboBox。问题是如何根据从字典中获取的数据选择 QTableView() 中的组合框中的项目

我发现我应该应用 self.combo.setCurrentIndex(self.combo.findText( status_str)) 但无法理解如何获取该变量 status_str comboBox 或放置在代码中应用它的位置。另外,我无法理解如何使 comboBox 仅在双击后才出现。如果单元格没有被双击,它看起来一定像任何其他单元格。

代码示例:

data = {"first":{"status":"closed"},"second":{"status":"expired"},"third":{ "status":"cancelled"}}
class ComboDelegate(QItemDelegate):
def __init__(self, parent):
QItemDelegate.__init__(self, parent)
def paint(self, painter, option, index):
self.combo = QComboBox(self.parent())
li = []
li.append("closed")
li.append("expired")
li.append("cancelled")
li.append("waiting")
self.combo.addItems(li)
#self.combo.setCurrentIndex(self.combo.findText( status_str ))
if not self.parent().indexWidget(index):
self.parent().setIndexWidget( index, self.combo )

class TableView(QTableView):
def __init__(self, *args, **kwargs):
QTableView.__init__(self, *args, **kwargs)
self.setItemDelegateForColumn(1, ComboDelegate(self))

class MainFrame(QWidget):
def __init__(self):
QWidget.__init__(self)
table = TableView(self)
self.model = QStandardItemModel()
table.setModel(self.model)
MainWindow = QVBoxLayout()
MainWindow.addWidget(table)
self.setLayout(MainWindow)
self.fillModel()

def fillModel(self):
for i in data:
print i
name_str = i
status_str = data[i]["status"]
name = QStandardItem(name_str)
status = QStandardItem(status_str)
items = [name, status]
self.model.appendRow(items)

if __name__ == "__main__":
app = QApplication(sys.argv)
main = MainFrame()
main.show()
main.move(app.desktop().screen().rect().center() - main.rect().center())
sys.exit(app.exec_())

最佳答案

重写QItemDelegate.paint不是创建委托(delegate)的推荐方法。 QItemDelegate 具有诸如 createEditorsetEditorData 之类的方法,您应该重写它们。这些方法由 Qt 适当调用。

createEditor 中,您应该创建您的 comboBox 并返回它。例如:

def createEditor(self, parent, option, index):
editor = QComboBox(parent)
li = []
li.append("closed")
li.append("expired")
li.append("cancelled")
li.append("waiting")
editor.addItems(li)
return editor

setEditorData中,您可以在模型中查询组合框的当前索引。这将被称为例如:

def setEditorData(self, editor, index):
value = index.model().data(index, Qt.EditRole)
editor.setCurrentIndex(editor.findText(value))

请注意,在此示例中,我依靠 QItemDelegate.setModelData() 的默认实现将 combobox 的当前文本保存到 编辑角色。如果您想做更复杂的事情(例如保存组合框索引而不是文本),您可以将数据保存/恢复到不同的角色(例如Qt.UserRole) >) 在这种情况下,您可以修改在 setEditorData 方法中获取角色的位置,并重写 setModelData ,如下所示:

def setEditorData(self, editor, index):
value = index.model().data(index, Qt.UserRole)
editor.setCurrentIndex(int(value))

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

这是上述代码的最小工作示例!请注意,我已使用 sip 关闭了对 QVariant 的支持,以便模型返回 native Python 类型。

import sys
import sip
sip.setapi('QVariant', 2)
from PyQt4.QtGui import *
from PyQt4.QtCore import *


data = {"first":{"status":"closed"},"second":{"status":"expired"},"third":{ "status":"cancelled"}}

class ComboDelegate(QItemDelegate):

def createEditor(self, parent, option, index):
editor = QComboBox(parent)
li = []
li.append("closed")
li.append("expired")
li.append("cancelled")
li.append("waiting")
editor.addItems(li)
return editor

def setEditorData(self, editor, index):
value = index.model().data(index, Qt.EditRole)
editor.setCurrentIndex(editor.findText(value))


class Example(QMainWindow):

def __init__(self):
super(Example, self).__init__()

self.tableview = QTableView()
self.tableview.setItemDelegateForColumn(1, ComboDelegate())

self.setCentralWidget(self.tableview)

self.model = QStandardItemModel()
self.tableview.setModel(self.model)
self.fillModel()

self.show()

def fillModel(self):
for i in data:
name_str = i
status_str = data[i]["status"]
name = QStandardItem(name_str)
status = QStandardItem(status_str)
items = [name, status]
self.model.appendRow(items)


if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
<小时/>

编辑

我刚刚注意到您关于双击后自动显示组合框的其他问题。我有一个我以前用过的技巧来做到这一点。它依赖于将 View 传递给委托(delegate)并将以下几行添加到 createEditor 方法中:

        editor.activated.connect(lambda index, editor=editor: self._view.commitData(editor))
editor.activated.connect(lambda index, editor=editor: self._view.closeEditor(editor,QAbstractItemDelegate.NoHint))
QTimer.singleShot(10,editor.showPopup)

完整的工作示例:

import sys
import sip
sip.setapi('QVariant', 2)
from PyQt4.QtGui import *
from PyQt4.QtCore import *


data = {"first":{"status":"closed"},"second":{"status":"expired"},"third":{ "status":"cancelled"}}

class ComboDelegate(QItemDelegate):
def __init__(self, view):
QItemDelegate.__init__(self)
self._view = view


def createEditor(self, parent, option, index):
editor = QComboBox(parent)
li = []
li.append("closed")
li.append("expired")
li.append("cancelled")
li.append("waiting")
editor.addItems(li)


editor.activated.connect(lambda index, editor=editor: self._view.commitData(editor))
editor.activated.connect(lambda index, editor=editor: self._view.closeEditor(editor,QAbstractItemDelegate.NoHint))
QTimer.singleShot(10,editor.showPopup)

return editor

def setEditorData(self, editor, index):
value = index.model().data(index, Qt.EditRole)
editor.setCurrentIndex(editor.findText(value))


class Example(QMainWindow):

def __init__(self):
super(Example, self).__init__()

self.tableview = QTableView()
self.tableview.setItemDelegateForColumn(1, ComboDelegate(self.tableview))

self.setCentralWidget(self.tableview)

self.model = QStandardItemModel()
self.tableview.setModel(self.model)
self.fillModel()

self.show()

def fillModel(self):
for i in data:
name_str = i
status_str = data[i]["status"]
name = QStandardItem(name_str)
status = QStandardItem(status_str)
items = [name, status]
self.model.appendRow(items)


if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())

关于python - 如何恢复 QTableView 中 QComboBox 委托(delegate)的索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31367097/

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