【问题标题】:Text styling in QTableView with PySide2使用 PySide2 在 QTableView 中设置文本样式
【发布时间】:2019-01-18 23:41:20
【问题描述】:

我有一个填充了适当模型的 QTableView。 我想根据上下文更改文本的样式:

文本,如果括号之间有什么东西,只是这部分文本应该变成绿色-包括括号-(和粗体,只要不是更难)。

如果你能提供一个sn-p或超级简单的例子,我很感激。

【问题讨论】:

  • 据我了解,您希望括号中的文本加上括号变为绿色或粗体,其余的保持不变,对吗?
  • 是的,正是,谢谢!!绿色,或绿色和粗体,但不仅仅是粗体。
  • 所以,直接回答你的问题,不要绕太多圈
  • @eyllanesc,现在这很简单直接,你能帮帮我吗?

标签: python qtableview pyside2


【解决方案1】:

你必须使用一个使用QTextDocument的委托:

import random
from PySide2 import QtCore, QtGui, QtWidgets

words = '''Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
Mauris euismod cursus mi sit amet pellentesque. 
Proin sed lectus sed augue scelerisque congue eget quis leo. 
Curabitur ultrices nisi nisi, placerat gravida urna sagittis et. 
Nullam vitae urna tortor. Curabitur a lobortis metus, et laoreet arcu. 
Quisque a mi in purus molestie porta non sit amet purus. 
Sed porta non purus et suscipit.'''.split()

class HighlightDelegate(QtWidgets.QStyledItemDelegate):
    def __init__(self, parent=None):
        super(HighlightDelegate, self).__init__(parent)
        self.doc = QtGui.QTextDocument(self)
        self._regex = QtCore.QRegularExpression()
        self._highlight_format = QtGui.QTextCharFormat()

    def paint(self, painter, option, index):
        painter.save()
        options = QtWidgets.QStyleOptionViewItem(option)
        self.initStyleOption(options, index)
        self.doc.setPlainText(options.text)
        self.apply_highlight()
        options.text = ""
        style = QtWidgets.QApplication.style() if options.widget is None \
            else options.widget.style()
        style.drawControl(QtWidgets.QStyle.CE_ItemViewItem, options, painter)

        ctx = QtGui.QAbstractTextDocumentLayout.PaintContext()
        if option.state & QtWidgets.QStyle.State_Selected:
            ctx.palette.setColor(QtGui.QPalette.Text, option.palette.color(
                QtGui.QPalette.Active, QtGui.QPalette.HighlightedText))
        else:
            ctx.palette.setColor(QtGui.QPalette.Text, option.palette.color(
                QtGui.QPalette.Active, QtGui.QPalette.Text))

        textRect = style.subElementRect(
            QtWidgets.QStyle.SE_ItemViewItemText, options)

        if index.column() != 0:
            textRect.adjust(5, 0, 0, 0)

        the_constant = 4
        margin = (option.rect.height() - options.fontMetrics.height()) // 2
        margin = margin - the_constant
        textRect.setTop(textRect.top() + margin)

        painter.translate(textRect.topLeft())
        painter.setClipRect(textRect.translated(-textRect.topLeft()))
        self.doc.documentLayout().draw(painter, ctx)

        painter.restore()

    def apply_highlight(self):
        cursor = QtGui.QTextCursor(self.doc)
        cursor.beginEditBlock()
        highlightCursor = QtGui.QTextCursor(self.doc)
        while not highlightCursor.isNull() and not highlightCursor.atEnd():
            highlightCursor = self.doc.find(self.regex, highlightCursor)
            if not highlightCursor.isNull():
                highlightCursor.mergeCharFormat(self.highlightFormat)
        cursor.endEditBlock()

    @property
    def regex(self):
        return self._regex

    @regex.setter
    def regex(self, regex):
        if self._regex == regex: return
        self._regex = regex

    @property
    def highlightFormat(self):
        return self._highlight_format

    @highlightFormat.setter
    def highlightFormat(self, fmt):
        self._highlight_format = fmt

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.table = QtWidgets.QTableView()

        self._delegate = HighlightDelegate(self.table)
        self._delegate.regex = QtCore.QRegularExpression(r"\(.*?\)")
        fmt = QtGui.QTextCharFormat()
        fmt.setForeground(QtCore.Qt.green)
        fmt.setFontWeight(QtGui.QFont.Bold)
        self._delegate.highlightFormat = fmt
        self.table.setItemDelegate(self._delegate)

        model = QtGui.QStandardItemModel(10, 4)
        for i in range(model.rowCount()):
            for j in range(model.columnCount()):
                item = QtGui.QStandardItem("{}({}){}".format(*random.sample(words,3)))
                model.setItem(i, j, item)
        self.table.setModel(model)
        self.setCentralWidget(self.table)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

【讨论】:

  • @eyllanesc ...我正在尝试将您的示例转换为 pyqt4 ...任何帮助将不胜感激。 :)
  • @panofish python2 还是 python3?
  • @eyllanesc .. python2... 我还更新了您尝试转换 https://stackoverflow.com/a/57064002/259538 的其他示例
  • @panofish 我已经添加了 PyQt4 的版本,稍后我也会为这个答案添加一个类似的版本。
  • @eyllanesc .. 你是我的英雄。 PyQt4 版本很好用!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-23
  • 2010-12-11
相关资源
最近更新 更多