我基于QAbstractTableModel创建一个类“ pandasModel”,如下所示:
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)
我还创建了一个QTableView来显示模型,如下所示:
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(240,255,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_())
在'data'函数中使用'return QBrush(Qt.red)'可以将单元格的背景色设置为'In error'值,但是在Qtableview创建完成时已经设置了背景色,我只想设置当我调用函数“ set_cell_color”时,显示单元格的背景颜色,这意味着即使已经创建了Qtableview,我也可以控制单元格的背景,我将非常感谢您的帮助。
逻辑是将信息关联到项目的位置和项目的颜色保存在模型中,并对其进行更新,必须发出dataChanged信号。
注意:您的模型属于表类型,因此您必须继承自QAbstractTableModel而不是QAbstractItemModel
考虑到上述情况,解决方案是:
class pandasModel(QAbstractTableModel):
def __init__(self, data, parent=None):
QAbstractItemModel.__init__(self, parent)
self._data = data
self.colors = dict()
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()])
if role == Qt.BackgroundRole:
color = self.colors.get((index.row(), index.column()))
if color is not None:
return color
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)
def change_color(self, row, column, color):
ix = self.index(row, column)
self.colors[(row, column)] = color
self.dataChanged.emit(ix, ix, (Qt.BackgroundRole,))
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]])
self.model = pandasModel(data)
self.table.setModel(self.model)
def set_cell_color(self, row, column):
self.model.change_color(row, column, QBrush(Qt.red))
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句