python - 使用 QSortFilterProxyModel 时的 pyQt5 段错误
问题描述
在我的 Mac 上将 QSortFilterProxy 与 PyQT5 和 python3 一起使用时,我一直遇到段错误 (11)。
该表按预期出现,并且能够很好地排序。但是,当添加一个项目,然后尝试进行后续排序时,gui 会因“segfault 11”而崩溃
我的研究没有成果。我希望这里有人可以提供帮助。以下代码是一个简单的示例。
#! /Library/Frameworks/Python.framework/Versions/3.8/bin/python3
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt, QObject
from PyQt5.QtWidgets import (QApplication,
QTableView, QWidget,QPushButton,
QVBoxLayout,QMainWindow)
import sys
class MyModel(QtCore.QAbstractTableModel) :
def __init__(self,data=None,parent = None, *args) :
super(MyModel,self).__init__(parent,*args)
self.data = data or []
#Add item to the data.
def addItem(self,item) :
#add the item to to the model data.
self.data.append(item)
#Emit signal to the TableView to redraw
self.layoutChanged.emit()
#Overloaded function that must be defined.
def data(self,index,role) :
#The index (contains both x,y) and role are passed.
#The roles give instructions about how to display the model.
row = index.row()
col = index.column()
#Insert the appropriate information into the display, based
#on the column.
if role == Qt.DisplayRole :
item = self.data[row]
if (col == 0) :
return(item.name)
if (col == 1) :
return(item.num)
#rowCount must be overloaded
def rowCount(self,index) :
return(len(self.data))
#columnCount must be overloaded
def columnCount(self,index) :
return(2)
#Display headers for the columns
def headerData(self,section,orientation,role) :
if (role != Qt.DisplayRole) :
return
if (orientation != Qt.Horizontal) :
return
if (section == 0) :
return("Name")
if (section == 1) :
return("Number")
class MainWindow(QtWidgets.QMainWindow) :
def __init__(self,*args,**kwargs) :
super(MainWindow,self).__init__(*args,**kwargs)
self.data = []
proxymodel = QtCore.QSortFilterProxyModel()
proxymodel.setDynamicSortFilter(True)
proxymodel.setFilterKeyColumn(0)
self.proxymodel = proxymodel
#Create the TableView widget that will display the model
self.mytable = QtWidgets.QTableView()
self.mytable.setSortingEnabled(True)
#Create the model that will be displayed in the table
self.mymodel = MyModel(self.data)
#Assign the model to the table
self.mytable.setModel(proxymodel)
self.proxymodel.setSourceModel(self.mymodel)
#Put the table in the main widget's layout.
#Need to have a layout for its size hint.
layout = QtWidgets.QHBoxLayout()
layout.addWidget(self.mytable,0,Qt.AlignHCenter)
button = QPushButton("Add Item",self)
button.clicked.connect(self.addItem)
layout.addWidget(button)
self.layout = layout
#The actual widget.
widget = QtWidgets.QWidget()
widget.setLayout(layout)
#Show the results
self.setCentralWidget(widget)
self.show()
for i in range(10) :
item = Item(i)
self.mymodel.addItem(item)
def addItem(self) :
num = len(self.mymodel.data)
item = Item(num)
self.mymodel.addItem(item)
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
app.exec()
提前致谢
解决方案
问题不是 QSortFilterProxyModel 而是源模型的错误实现。另一方面,虽然使用 layoutAboutToBeChanged 解决问题不是合适的选项,如文档中所述,如果您想向模型添加行,那么您必须使用将在内部调用 layoutAboutToBeChanged 信号的beginInsertRows()
andendInsertRows()
方法,考虑到上述情况,最合适的实现是:
class MyModel(QtCore.QAbstractTableModel):
def __init__(self, data=None, parent=None, *args):
super(MyModel, self).__init__(parent, *args)
self.data = data or []
# Add item to the data.
def addItem(self, item):
self.beginInsertRows(QtCore.QModelIndex(), self.rowCount(), self.rowCount())
self.data.append(item)
self.endInsertRows()
def data(self, index, role):
if not index.isValid():
return
row = index.row()
col = index.column()
if (row < 0 or row >= self.rowCount()) and (
col < 0 or col >= self.columnCount()
):
return
if role == Qt.DisplayRole:
item = self.data[row]
if col == 0:
return item.name
if col == 1:
return item.num
def rowCount(self, index=QtCore.QModelIndex()):
return len(self.data)
def columnCount(self, index=QtCore.QModelIndex()):
return 2
def headerData(self, section, orientation, role):
if role != Qt.DisplayRole:
return
if orientation != Qt.Horizontal:
return
if section == 0:
return "Name"
if section == 1:
return "Number"
推荐阅读
- sql - Excel 日期作为 44381 插入 SQL Server 表
- php - Facebook - iOS 更新 - /insight 中缺少数据
- javascript - 如何在香草 javascript 中用逗号编码计数动画?
- php - 上传前的 Laravel 裁剪图像
- java - 禁止,Http.status=403 与 jdbcAuthentication()
- reactjs - 在 react 组件中,为什么可以在与 useEffect 一起使用的事件处理程序中访问 useState-function,而相应的 useState-variable 不能?
- excel - Excel 条形图宽度
- javascript - 如何使用 ElectronJS 中的请求获取特定的类/xpath 数据
- html - 如何在行之间添加间距css
- mongodb - 如何禁用 MongoDB 聚合超时