Python 如何在使用自定义QAbstractTableModel创建Qtableview后为单元格着色
我基于QabStretctTableModel创建了一个类“PandaModel”,如下所示:Python 如何在使用自定义QAbstractTableModel创建Qtableview后为单元格着色,python,pyqt,qtableview,qabstracttablemodel,Python,Pyqt,Qtableview,Qabstracttablemodel,我基于QabStretctTableModel创建了一个类“PandaModel”,如下所示: import sys from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtCore import * class pandasModel(QAbstractItemModel): def __init__(self, data, parent=None): QAbstractI
import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class pandasModel(QAbstractItemModel):
def __init__(self, data, parent=None):
QAbstractItemModel.__init__(self, parent)
self._data = data
def rowCount(self, parent=None):
return self._data.index.size
def columnCount(self, parent=None):
return self._data.columns.size
def data(self, index, role=Qt.DisplayRole):
if index.isValid():
if role == Qt.DisplayRole:
return str(self._data.iloc[index.row(), index.column()])
if role == Qt.EditRole:
return str(self._data.iloc[index.row(), index.column()])
return None
def headerData(self, rowcol, orientation, role):
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return self._data.columns[rowcol]
if orientation == Qt.Vertical and role == Qt.DisplayRole:
return self._data.index[rowcol]
return None
def flags(self, index):
flags = super(self.__class__, self).flags(index)
flags |= Qt.ItemIsEditable
flags |= Qt.ItemIsSelectable
flags |= Qt.ItemIsEnabled
flags |= Qt.ItemIsDragEnabled
flags |= Qt.ItemIsDropEnabled
return flags
def sort(self, Ncol, order):
"""Sort table by given column number.
"""
try:
self.layoutAboutToBeChanged.emit()
self._data = self._data.sort_values(self._data.columns[Ncol], ascending=not order)
self.layoutChanged.emit()
except Exception as e:
print(e)
class TableWin(QWidget):
pos_updown = -1
pos_save = []
def __init__(self):
super(TableWin, self).__init__()
self.resize(200, 100)
self.table = QTableView(self)
self.v_layout = QVBoxLayout()
self.v_layout.addWidget(self.table)
self.setLayout(self.v_layout)
self.showdata()
def showdata(self):
data = pd.DataFrame([[1,2,3,4],[5,6,7,8]])
model = pandasModel(data)
self.table.setModel(model)
def set_cell_color(self, row, column)
'''
Pass two arguments to this function, which is called to set
the background color of the cell corresponding to the row and column
'''
if __name__ == '__main__':
app = QApplication(sys.argv)
tableView = TableWin()
# I want to change cell's color by call function 'set_cell_color' here
# tableView.set_cell_color(row=1,column=1)
tableView.show()
sys.exit(app.exec_())
我还创建了一个QTableView来显示模型,如下所示:
import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class pandasModel(QAbstractItemModel):
def __init__(self, data, parent=None):
QAbstractItemModel.__init__(self, parent)
self._data = data
def rowCount(self, parent=None):
return self._data.index.size
def columnCount(self, parent=None):
return self._data.columns.size
def data(self, index, role=Qt.DisplayRole):
if index.isValid():
if role == Qt.DisplayRole:
return str(self._data.iloc[index.row(), index.column()])
if role == Qt.EditRole:
return str(self._data.iloc[index.row(), index.column()])
return None
def headerData(self, rowcol, orientation, role):
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return self._data.columns[rowcol]
if orientation == Qt.Vertical and role == Qt.DisplayRole:
return self._data.index[rowcol]
return None
def flags(self, index):
flags = super(self.__class__, self).flags(index)
flags |= Qt.ItemIsEditable
flags |= Qt.ItemIsSelectable
flags |= Qt.ItemIsEnabled
flags |= Qt.ItemIsDragEnabled
flags |= Qt.ItemIsDropEnabled
return flags
def sort(self, Ncol, order):
"""Sort table by given column number.
"""
try:
self.layoutAboutToBeChanged.emit()
self._data = self._data.sort_values(self._data.columns[Ncol], ascending=not order)
self.layoutChanged.emit()
except Exception as e:
print(e)
class TableWin(QWidget):
pos_updown = -1
pos_save = []
def __init__(self):
super(TableWin, self).__init__()
self.resize(200, 100)
self.table = QTableView(self)
self.v_layout = QVBoxLayout()
self.v_layout.addWidget(self.table)
self.setLayout(self.v_layout)
self.showdata()
def showdata(self):
data = pd.DataFrame([[1,2,3,4],[5,6,7,8]])
model = pandasModel(data)
self.table.setModel(model)
def set_cell_color(self, row, column)
'''
Pass two arguments to this function, which is called to set
the background color of the cell corresponding to the row and column
'''
if __name__ == '__main__':
app = QApplication(sys.argv)
tableView = TableWin()
# I want to change cell's color by call function 'set_cell_color' here
# tableView.set_cell_color(row=1,column=1)
tableView.show()
sys.exit(app.exec_())
我们现在可以在QTableview中显示数据,但问题是我如何调用函数“set_cell_color”来设置给定行和列的单元格的背景色,所以您能告诉我如何在def set_cell_color中完成代码吗
一旦我想使用“model.item(row,col).setBackground(QColor(240255,240))”设置单元格的颜色,就像QStandardItemModel一样,但引发错误“model”没有属性“item”
代码如下:
import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class Model(QAbstractTableModel):
def __init__(self, parent=None):
super(Model, self).__init__(parent)
self._data = [[['%d - %d' % (i, j), False] for j in range(10)] for i in range(10)]
def rowCount(self, parent):
return len(self._data)
def columnCount(self, parent):
return len(self._data[0])
def flags(self, index):
return Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable
def data(self, index, role):
if index.isValid():
data, changed = self._data[index.row()][index.column()]
if role in [Qt.DisplayRole, Qt.EditRole]:
return data
if role == Qt.BackgroundRole and data == "In error": # <---------
return QBrush(Qt.red)
def setData(self, index, value, role):
if role == Qt.EditRole:
self._data[index.row()][index.column()] = [value, True]
self.dataChanged.emit(index, index)
return True
return False
if __name__ == '__main__':
app = QApplication(sys.argv)
tableView = QTableView()
m = Model(tableView)
tableView.setModel(m)
tableView.show()
sys.exit(app.exec_())
导入系统
从PyQt5.QtGui导入*
从PyQt5.QtWidgets导入*
从PyQt5.QtCore导入*
类模型(QAbstractTableModel):
def uuu init uuu(self,parent=None):
超级(模型,自我).\uuuu初始\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
self.\u data=[[['%d-%d'(i,j),对于范围(10)中的j为False]i对于范围(10)]
def行数(自身、父级):
返回长度(自身数据)
def列数(自身、父项):
返回长度(自身数据[0])
def标志(自、索引):
返回Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable
def数据(自身、索引、角色):
如果index.isValid():
数据,已更改=self.\u数据[index.row()][index.column()]
如果[Qt.DisplayRole,Qt.EditRole]中的角色:
返回数据
如果role==Qt.BackgroundRole and data==“In error”:#逻辑是将项目位置和项目颜色关联的信息保存在模型中,并进行更新,必须发出dataChanged信号 注意:您的模型属于table类型,因此您必须从QAbstractTableModel继承,而不是从QAbstractItemModel继承 考虑到上述情况,解决方案是: 类pandasModel(QAbstractTableModel): def uuu init uuu(self,data,parent=None): QAbstractItemModel.\uuuuu init\uuuuuuu(自,父) self.\u data=数据 self.colors=dict() def行数(自身,父项=无): 返回self.\u data.index.size def columnCount(自身,父项=无): 返回self.\u data.columns.size def数据(self,index,role=Qt.DisplayRole): 如果index.isValid(): 如果角色==Qt.DisplayRole: 返回str(self.\u data.iloc[index.row(),index.column()) 如果角色==Qt.EditRole: 返回str(self.\u data.iloc[index.row(),index.column()) 如果角色==Qt.BackgroundRole: color=self.colors.get((index.row(),index.column()) 如果颜色不是无: 返回颜色 一无所获 def headerData(自身、行列、方向、角色): 如果方向==Qt.Horizontal且角色==Qt.DisplayRole: 返回self.\u数据列[rowcol] 如果方向==Qt.Vertical且角色==Qt.DisplayRole: 返回self.\u数据索引[rowcol] 一无所获 def标志(自、索引): flags=super(self.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu 标志|=Qt.ItemIsEditable 标志|=Qt.itemselectable 标志|=Qt.ItemIsEnabled 标志|=Qt.ItemIsDragEnabled 标志|=Qt.itemsropertable 返回标志 def排序(自身、Ncol、顺序): “”“按给定的列号对表进行排序。 """ 尝试: self.layoutaboutbechanged.emit() self.\u data=self.\u data.sort\u值( self.\u data.columns[Ncol],升序=非顺序 ) self.layoutChanged.emit() 例外情况除外,如e: 打印(e) def更改颜色(自身、行、列、颜色): ix=自索引(行、列) self.colors[(行、列)]=颜色 self.dataChanged.emit(ix,ix,(Qt.BackgroundRole,) 类TableWin(QWidget): 位置向上向下=-1 pos_save=[] 定义初始化(自): 超级(TableWin,self)。\uuuu init\uuuuu() 自我调整大小(200100) self.table=QTableView(self) self.v_layout=QVBoxLayout() self.v_layout.addWidget(self.table) self.setLayout(self.v_布局) self.showdata() def showdata(自): data=pd.DataFrame([[1,2,3,4],[5,6,7,8]] self.model=pandasModel(数据) self.table.setModel(self.model) def设置单元格颜色(自身、行、列): self.model.change_颜色(行、列、QBrush(Qt.red))
非常感谢,你解决了我的问题,真是太好了perfectly@xufang如果这个答案对您有帮助,请不要忘记标记为正确,如果您不知道如何做,请检查