【问题标题】:Python PyQt5 QTableView Change selected row BackgroundcolorPython PyQt5 QTableView 更改选定行背景颜色
【发布时间】:2022-02-07 20:59:36
【问题描述】:

我有一个带有 QAbstractTableModel 的 QTableView。单击一个单元格时,我想更改行背景颜色。我知道至少有两种方法可以在单击一个单元格时更改行背景颜色。一种是使用委托,另一种是使用 QAbstractTable 中的 setData 方法。但我一个都没有,,,哎呀。在这里,我尝试在 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_()

【问题讨论】:

    标签: pyqt5 selection qtableview


    【解决方案1】:

    解决了!用户鼠标点击时改变 QTableView Row 背景颜色的两种方法。

    1. 使用 QStyledItemDelegate。 子类 QStyledItemDelegate。您应该设置一个可以从类外部重置值的类属性(等 tableview 的 currentindex),通过这个,delegate 的默认循环将比较 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。另外,您应该设置一个类属性,而不是方法 data() 的默认循环将与类属性(tableview 的当前索引)进行比较。并设置背景颜色。代码:
        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,然后,当您使用 QAbstractTableModel 的 data() 方法或 QStyledItemDelege 中的 pain() 方法时,您应该设置相同的颜色。然后一切正常!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-04
      • 2012-07-12
      • 2011-08-14
      • 1970-01-01
      • 2018-03-04
      • 2016-09-10
      • 2014-10-21
      • 2011-03-11
      相关资源
      最近更新 更多