Python PyQt5 QTableView 改变选中行的背景色

Python PyQt5 QTableView Change selected row Backgroundcolor

我有一个带有 QAbstractTableModel 的 QTableView。我想在单击一个单元格时更改行背景颜色。我知道至少有两种方法可以在单击一个单元格时更改行背景颜色。一种是使用delegate,另一种是使用QAbstractTable中的setData方法。但是我有 none 个,,,哎呀。在这里,我尝试使用 QAbstractTable 中的 setData 方法来更改所选单元格的背景颜色,但失败了!你能帮我更正我的代码以改变整行的颜色而不仅仅是一个单元格吗?无论如何,改变单元格颜色是不行的!非常感谢!下面的代码

import sys
import typing
import numpy as np
import pandas as pd
from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication, QMainWindow, \
    QWidget, QTableView, QVBoxLayout
from PyQt5.QtCore import QAbstractTableModel, Qt, QModelIndex

class MyTableModel(QAbstractTableModel):
    def __init__(self, data:pd.DataFrame):
        super().__init__()
        self._data = data

    def data(self, index: QModelIndex, role: int = ...) -> typing.Any:
        if role==Qt.DisplayRole:
            value = str(self._data.iloc[index.row()][index.column()])
            return value

    def setData(self, index: QModelIndex, value: typing.Any, role: int = ...) -> bool:
        if not index.isValid():
            return False
        else:
            if role==Qt.BackgroundColorRole:
                self.dataChanged.emit(index, index, [role])
                return True


    def rowCount(self, parent: QModelIndex = ...) -> int:
        return self._data.shape[0]

    def columnCount(self, parent: QModelIndex = ...) -> int:
        return self._data.shape[1]


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.myTable = QTableView()
        df = self.get_DataFrame_Data()
        self.model = MyTableModel(df)
        self.myTable.setModel(self.model)
        self.myTable.clicked.connect(self.change_row_bgcolor)
        hlayout = QVBoxLayout()
        hlayout.addWidget(self.myTable)
        dummy_widget = QWidget()
        dummy_widget.setLayout(hlayout)
        self.setCentralWidget(dummy_widget)
        self.setFixedSize(600, 600)

    def get_DataFrame_Data(self):
        ndarray = np.random.randint(10, 50, (7, 3))
        df = pd.DataFrame(data=ndarray, columns=['col1','col2','col3'])
        return df

    def change_row_bgcolor(self, index):
        self.model.setData(index,Qt.red,Qt.BackgroundColorRole)


app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()

已解决!鼠标点击时改变QTableView行背景色的两种方法

  1. 使用 QStyledItemDelegate。 Subclass QStyledItemDelegate。您应该设置一个 class 属性(等 tableview 的当前索引),它可以从 class 外部重置值,这样,委托的默认循环将比较 tableview 的 currentindex.Code:
    class TableDelegate(QStyledItemDelegate):
        
        select_index = None
    
        def paint(self, painter: QtGui.QPainter, option: 'QStyleOptionViewItem', index: QtCore.QModelIndex) -> None:
            # option.state
            row = index.row()
            column = index.column()
            select_row = self.select_index.row()
            # self.initStyleOption(option,index)
            if row == select_row:
                # option.font.setItalic(True)
                option.font.setStyle(QFont.StyleOblique)
                bg = QColor(135, 206, 255)
                painter.fillRect(option.rect, bg)
                # painter.eraseRect(option.rect)
            QStyledItemDelegate.paint(self, painter, option, index)
  1. 使用QAbstractTableModel.Also,你应该设置一个class 属性,方法data()的默认循环将与class [=35=进行比较](tableview 的当前索引)。并设置背景 color.Code:
    class MyTableModel(QAbstractTableModel):
        def __init__(self, data:pd.DataFrame):
            super().__init__()
            self._data = data
            self.color_enabled = False
            self.color_back = Qt.magenta
            self.target_row = -1
    
        def data(self, index: QModelIndex, role: int) -> typing.Any:
            if role==Qt.DisplayRole:
                # print(index.row())
                value = str(self._data.iloc[index.row()][index.column()])
                return value
            if role == Qt.BackgroundRole and index.row()==self.target_row \
                    and self.color_enabled==True:
                return QBrush(self.color_back)

还有,,!这里还有一个特殊的问题需要强调。当用户单击一个单元格时,我在计算机中看到的默认背景是蓝色的。如果你想点击时整行的背景颜色相同,你应该在创建一个QTableView之后这样做:

self.myTable.setStyleSheet("QTableView::item:selected{"
                   "background:rgb(135, 206, 255)}")

也就是说,你通过QSS设置了选中单元格的bgcolor,然后无论是在QStyledItemDelege中使用QAbstractTableModel的data()方法还是pain()方法,都应该设置相同的颜色。然后一切就OK了!