错误是在insertRows()方法中。 意外在for loop重新声明了传入的row参数变量(已选择QModelIndex.row()号):
for row in range(rows):
我已经改名为参数row变量postion和固定的工作代码下面贴(在proxyB 。分类属性被注释掉它显示ViewB 。项目作为未分类的这种方式很容易看到一个“真实”的项目订单:
以后编辑:
对代码进行了一些其他调整。 “幕后”发生了很多事情:在insertRows()和removeRows() insertRows()之前或之后。
例如:
当我们调用这些方法时,提供的第一个参数必须是QModelIndex的行号。 方法将使用它作为“起点”或“起点行号”,从该起点将添加(插入)或删除索引:与第二个整数参数说的一样多。
众所周知, proxy model的modelIndexes的行号和列号与与之关联的sourceModel的modelIndexes不匹配。 有趣的是,在这两种方法甚至没有接收到行号参数之前,存在从proxy的行号到sourceModel的转换。 从打印输出中可以看出: buttonClicked()方法“发送”第0行,而insertRows()方法打印出它接收的行号不是0(如果是从by-Proxy-驱动的TableView,并启用并启用了排序或过滤功能)。
除此之外,这两种方法如何从model的self.items变量中删除或弹出数据,还存在一些“复杂”的机制。 如果行号未按顺序排列,则removeRows()方法会“返回”自身以完成作业。 完整的工作代码如下:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
class Model(QAbstractTableModel):
def __init__(self, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.items = ['Item_A000','Item_B001','Item_A002','Item_B003','Item_B004']
self.numbers=[20,10,30,50,40]
self.added=0
def rowCount(self, parent=QModelIndex()):
return len(self.items)
def columnCount(self, parent=QModelIndex()):
return 2
def data(self, index, role):
if not index.isValid(): return QVariant()
elif role != Qt.DisplayRole:
return QVariant()
row=index.row()
column=index.column()
if column==0:
if row
return QVariant(self.items[row])
elif column==1:
if row
return QVariant( self.numbers[row] )
else:
return QVariant()
def removeRows(self, position, rows=1, index=QModelIndex()):
print "\n\t\t ...removeRows() Starting position: '%s'"%position, 'with the total rows to be deleted: ', rows
self.beginRemoveRows(QModelIndex(), position, position + rows - 1)
self.items = self.items[:position] + self.items[position + rows:]
self.endRemoveRows()
return True
def insertRows(self, position, rows=1, index=QModelIndex()):
print "\n\t\t ...insertRows() Starting position: '%s'"%position, 'with the total rows to be inserted: ', rows
indexSelected=self.index(position, 0)
itemSelected=indexSelected.data().toPyObject()
self.beginInsertRows(QModelIndex(), position, position + rows - 1)
for row in range(rows):
self.items.insert(position + row, "%s_%s"% (itemSelected, self.added))
self.added+=1
self.endInsertRows()
return True
class Proxy(QSortFilterProxyModel):
def __init__(self):
super(Proxy, self).__init__()
def filterAcceptsRow(self, rowProc, parentProc):
modelIndex=self.sourceModel().index(rowProc, 0, parentProc)
item=self.sourceModel().data(modelIndex, Qt.DisplayRole).toPyObject()
if item and 'B' in item:
return True
else: return False
class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
vLayout=QVBoxLayout(self)
self.setLayout(vLayout)
hLayout=QHBoxLayout()
vLayout.insertLayout(0, hLayout)
tableModel=Model(self)
proxyB=Proxy()
proxyB.setSourceModel(tableModel)
self.ViewA=QTableView(self)
self.ViewA.setModel(tableModel)
self.ViewA.clicked.connect(self.viewClicked)
self.ViewB=QTableView(self)
self.ViewB.setModel(proxyB)
self.ViewB.clicked.connect(self.viewClicked)
self.ViewB.setSortingEnabled(True)
self.ViewB.sortByColumn(0, Qt.AscendingOrder)
self.ViewB.setSelectionBehavior(QTableView.SelectRows)
hLayout.addWidget(self.ViewA)
hLayout.addWidget(self.ViewB)
insertButton=QPushButton('Insert Row Above Selection')
insertButton.setObjectName('insertButton')
insertButton.clicked.connect(self.buttonClicked)
removeButton=QPushButton('Remove Selected Item')
removeButton.setObjectName('removeButton')
removeButton.clicked.connect(self.buttonClicked)
vLayout.addWidget(insertButton)
vLayout.addWidget(removeButton)
def getZeroColumnSelectedIndexes(self, tableView=None):
if not tableView: return
selectedIndexes=tableView.selectedIndexes()
if not selectedIndexes: return
return [index for index in selectedIndexes if not index.column()]
def viewClicked(self, indexClicked):
print 'indexClicked() row: %s column: %s'%(indexClicked.row(), indexClicked.column() )
proxy=indexClicked.model()
def buttonClicked(self):
button=self.sender()
if not button: return
tableView=None
if self.ViewA.hasFocus(): tableView=self.ViewA
elif self.ViewB.hasFocus(): tableView=self.ViewB
if not tableView: print 'buttonClicked(): not tableView'; return
zeroColumnSelectedIndexes=self.getZeroColumnSelectedIndexes(tableView)
if not zeroColumnSelectedIndexes: print 'not zeroColumnSelectedIndexes'; return
firstZeroColumnSelectedIndex=zeroColumnSelectedIndexes[0]
if not firstZeroColumnSelectedIndex or not firstZeroColumnSelectedIndex.isValid():
print 'buttonClicked(): not firstZeroColumnSelectedIndex.isValid()'; return
startingRow=firstZeroColumnSelectedIndex.row()
print '\n buttonClicked() startingRow =', startingRow
if button.objectName()=='removeButton':
tableView.model().removeRows(startingRow, len(zeroColumnSelectedIndexes), QModelIndex())
elif button.objectName()=='insertButton':
tableView.model().insertRows(startingRow, len(zeroColumnSelectedIndexes), QModelIndex())
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())