【问题标题】:pyqt stylesheet based styling of TableView cells based on content基于 pyqt 样式表的基于内容的 TableView 单元格样式
【发布时间】:2018-10-12 12:57:08
【问题描述】:

我找到了一种方法,可以根据单元格中的内容在 TableView 中进行基于 css 的单元格样式。以下代码显示了一个示例:

#!/usr/bin/python3

from PyQt5 import QtWidgets, QtGui, QtCore

class_values = ["zero", "one", "two"]

class Cell(QtWidgets.QWidget):
    def initFromItem(self, item):
        self.setProperty('dataClass', class_values[int(item.text())])

class TDelegate(QtWidgets.QStyledItemDelegate):
    def __init__(self, *a):
        super(TDelegate, self).__init__(*a)
        self.cell = Cell(self.parent())

    def paint(self, painter, option, index):
        item = index.model().itemFromIndex(index)
        self.cell.initFromItem(item)
        self.initStyleOption(option, index)
        style = option.widget.style() if option.widget else QtWidgets.QApplication.style()
        style.unpolish(self.cell)
        style.polish(self.cell)
        style.drawControl(QtWidgets.QStyle.CE_ItemViewItem, option, painter, self.cell)

class TTableModel(QtGui.QStandardItemModel):
    def __init__(self, parent=None):
        super(TTableModel, self).__init__(parent)
        for i in range(5):
            self.appendRow([QtGui.QStandardItem(str((x+i) % 3)) for x in range(5)])

class TTableView(QtWidgets.QTableView):
    def __init__(self, parent=None):
        super(TTableView, self).__init__(parent)
        self.setItemDelegate(TDelegate(self))

class Main(QtWidgets.QMainWindow):
    def __init__(self):
        super(Main, self).__init__()
        self.table = TTableView(self)
        self.model = TTableModel(self)
        self.table.setModel(self.model)
        self.setCentralWidget(self.table)

if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    app.setStyleSheet("""
Cell[dataClass=zero]::item { background-color: gray; }
Cell[dataClass=one]::item { background-color: green; font-style: italic }
Cell[dataClass=two]::item { font-weight: bold }
""")
    mainWin = Main()
    mainWin.show()
    sys.exit(app.exec_())

这会生成一个像这样的表:

具有每个单元格样式的 TableView

问题是虽然颜色有效,但字体样式却没有效果。我究竟做错了什么?我怎样才能改进我的代码?它是如何工作的?例如,为什么 CSS 选择器必须包含 ::item。收到所有答案。但请记住,对基于 CSS 的样式的需求对于项目来说是必不可少的。

【问题讨论】:

  • background-color 有效,因为它是QTableView::item 的属性,但在font 的情况下,它不是因为它不起作用。

标签: python pyqt pyqt5


【解决方案1】:

这是由于 qt (v5.9.5) 中的错误导致在创建 CE_ItemViewItem 时忽略所有字体样式信息(请参阅 QStyleSheetStyle::drawControl)。通过创建诸如CE_ToolBoxTabLabel 之类的其他东西来作弊(它可以正确处理drawControl 中的字体)确实可以让您格式化字体,但可以让您获得颜色,因为渲染使用的是按钮面板,而不是选项中指定的面板(或相关的 CSS)。所以你可以有一个或另一个,但不能同时拥有。我知道没有解决方法。

至于这是如何工作的。在QStyleSheetStyle::drawControl for a CE_ItemViewItem 中,查找::item 的子角色的CSS,如果存在,则应用于选项的副本(但不是字体样式),然后根据更新的项目绘制选项及其更新的调色板。不幸的是,由于无法从 PyQt 应用样式表(因为 QStyleSheet 不是 Qt 的公共 API 的一部分),因此无法破解此代码。

【讨论】:

    猜你喜欢
    • 2018-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-11
    • 2015-04-03
    相关资源
    最近更新 更多