gpt4 book ai didi

python - 从 QAbstractListModel 中插入和删除项目

转载 作者:行者123 更新时间:2023-12-01 05:42:15 25 4
gpt4 key购买 nike

我正在尝试创建一个 QAbstractListView 以与 QComboBox 一起使用,该 QComboBox 维护其包含的项目的排序列表。我在下面提供了一些示例代码来说明我的问题。当我更新列表中的项目时,组合框的 currentIndex 不会更新以反射(reflect)模型的更改。我尝试过使用 rowsAboutToBeInserted 和 rowsInserted 信号,但看不到任何效果(也许我做错了?)。

我的实际用例有点复杂,但示例应该足够了。正在排序的项目不仅仅是字符串,需要花费更多的精力来排序并拥有与其 DisplayRole 不同的 ItemDataRole。

itemsAdded 和 itemsRemoved 是我自己的函数,它们将连接到我尝试代理的另一个列表中的信号。

要触发该问题,请按“插入“c””按钮。字符串已正确插入到列表中,但选择范围从“e”移动到“d”(即选择索引不变)。

example code

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from PyQt4 import QtCore, QtGui

class Model(QtCore.QAbstractListModel):
def __init__(self, *args, **kwargs):
QtCore.QAbstractListModel.__init__(self, *args, **kwargs)
self.items = []

def rowCount(self, parent=QtCore.QModelIndex()):
return len(self.items)

def data(self, index, role=QtCore.Qt.DisplayRole):
if index.isValid() is True:
if role == QtCore.Qt.DisplayRole:
return QtCore.QVariant(self.items[index.row()])
elif role == QtCore.Qt.ItemDataRole:
return QtCore.QVariant(self.items[index.row()])
return QtCore.QVariant()

def itemsAdded(self, items):
# insert items into their sorted position
items = sorted(items)
row = 0
while row < len(self.items) and len(items) > 0:
if items[0] < self.items[row]:
self.items[row:row] = [items.pop(0)]
row += 1
row += 1
# add remaining items to end of list
if len(items) > 0:
self.items.extend(items)

def itemsRemoved(self, items):
# remove items from list
for item in items:
for row in range(0, len(self.items)):
if self.items[row] == item:
self.items.pop(row)
break

def main():
app = QtGui.QApplication([])
w = QtGui.QWidget()
w.resize(300,300)
layout = QtGui.QVBoxLayout()

model = Model()
model.itemsAdded(['a','b','d','e'])

combobox = QtGui.QComboBox()
combobox.setModel(model)
combobox.setCurrentIndex(3)
layout.addWidget(combobox)

def insertC(self):
model.itemsAdded('c')

button = QtGui.QPushButton('Insert "c"')
button.clicked.connect(insertC)
layout.addWidget(button)

w.setLayout(layout)
w.show()
app.exec_()

if __name__ == '__main__':
main()

最佳答案

下面是基于 Tim 的回答的完整工作示例。

不需要调用 setCurrentIndex。当正确调用 insertRows/removeRows 时, View 会自动跟踪这一点。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from PyQt4 import QtCore, QtGui

class Model(QtCore.QAbstractListModel):
def __init__(self, *args, **kwargs):
QtCore.QAbstractListModel.__init__(self, *args, **kwargs)
self.items = []

def rowCount(self, parent=QtCore.QModelIndex()):
return len(self.items)

def data(self, index, role=QtCore.Qt.DisplayRole):
if index.isValid() is True:
if role == QtCore.Qt.DisplayRole:
return QtCore.QVariant(self.items[index.row()])
elif role == QtCore.Qt.ItemDataRole:
return QtCore.QVariant(self.items[index.row()])
return QtCore.QVariant()

def itemsAdded(self, items):
# insert items into their sorted position
items = sorted(items)
row = 0
while row < len(self.items) and len(items) > 0:
if items[0] < self.items[row]:
self.beginInsertRows(QtCore.QModelIndex(), row, row)
self.items.insert(row, items.pop(0))
self.endInsertRows()
row += 1
row += 1
# add remaining items to end of the list
if len(items) > 0:
self.beginInsertRows(QtCore.QModelIndex(), len(self.items), len(self.items) + len(items) - 1)
self.items.extend(items)
self.endInsertRows()

def itemsRemoved(self, items):
# remove items from the list
for item in items:
for row in range(0, len(self.items)):
if self.items[row] == item:
self.beginRemoveRows(QtCore.QModelIndex(), row, row)
self.items.pop(row)
self.endRemoveRows()
break

def main():
app = QtGui.QApplication([])
w = QtGui.QWidget()
w.resize(300,200)
layout = QtGui.QVBoxLayout()

model = Model()
model.itemsAdded(['a','b','d','e'])

combobox = QtGui.QComboBox()
combobox.setModel(model)
combobox.setCurrentIndex(3)
layout.addWidget(combobox)

def insertC(self):
model.itemsAdded('c')

def removeC(self):
model.itemsRemoved('c')

buttonInsert = QtGui.QPushButton('Insert "c"')
buttonInsert.clicked.connect(insertC)
layout.addWidget(buttonInsert)

buttonRemove = QtGui.QPushButton('Remove "c"')
buttonRemove.clicked.connect(removeC)
layout.addWidget(buttonRemove)

w.setLayout(layout)
w.show()
app.exec_()

if __name__ == '__main__':
main()

关于python - 从 QAbstractListModel 中插入和删除项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17231184/

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