【问题标题】:How to display partially bold text in QListWidgetItem with QtCore.Qt.UserRole如何使用 QtCore.Qt.UserRole 在 QListWidgetItem 中显示部分粗体文本
【发布时间】:2019-05-03 07:57:05
【问题描述】:

我想在 QListWidgetItem 中以粗体显示单个单词。根据这个related post,应该可以使用QtCore.Qt.UserRole来达到这个目的。但是,提供的示例代码对我不起作用。 (由于我是初学者,我很可能忘记了一个定义,但我不知道是哪个。)

这是我目前所拥有的:

ma​​in.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>341</width>
    <height>244</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Dialog</string>
  </property>
  <widget class="QWidget" name="verticalLayoutWidget">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>10</y>
     <width>321</width>
     <height>231</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QListWidget" name="lwOptions"/>
    </item>
   </layout>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

test.py

import os
import sys
from PyQt5 import QtCore, uic
from PyQt5.Qt import QApplication, QDialog, QListWidgetItem

class GUI(QDialog):

    def __init__(self):
        super(GUI, self).__init__()
        dirname = os.path.dirname(os.path.abspath(__file__))
        uic.loadUi(os.path.join(dirname,'main.ui'), self)

        # this doesn't work
        for ordinal in ['first', 'second', 'third']:
            item = QListWidgetItem()
            item.setData(QtCore.Qt.UserRole, 'This is the <b>{}</b> word.'.format(ordinal)) 
            self.lwOptions.addItem(item)

        for ordinal in ['fourth', 'fifth', 'sixth']:
            item = QListWidgetItem('This is the <b>{}</b> word.'.format(ordinal))
            self.lwOptions.addItem(item)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = GUI()
    window.show()
    sys.exit(app.exec_())

当我运行代码时,它将添加三个空行和三个带有逐字消息的行。

正确的QtCore.Qt.UserRole 语法是什么?

【问题讨论】:

    标签: python pyqt pyqt5 styling qlistwidgetitem


    【解决方案1】:

    Qt 默认不使用角色&gt;= Qt::UserRole,因此它可以用于任何目的,例如保存附加信息,在这种情况下它不是解决方案。一种可能的解决方案是使用委托来呈现 HTML。

    import os
    import html
    from PyQt5 import QtCore, QtGui, QtWidgets, uic
    
    class HTMLDelegate(QtWidgets.QStyledItemDelegate):
        def __init__(self, parent=None):
            super(HTMLDelegate, self).__init__(parent)
            self.doc = QtGui.QTextDocument(self)
    
        def paint(self, painter, option, index):
            painter.save()
            options = QtWidgets.QStyleOptionViewItem(option)
            self.initStyleOption(options, index)
            self.doc.setHtml(options.text)
            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, None)
            if index.column() != 0:
                textRect.adjust(5, 0, 0, 0)
            constant = 4
            margin = (option.rect.height() - options.fontMetrics.height()) // 2
            margin = margin - 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 sizeHint(self, option, index):
            return QtCore.QSize(self.doc.idealWidth(), self.doc.size().height())
    
    class GUI(QtWidgets.QDialog):
        def __init__(self):
            super(GUI, self).__init__()
            dirname = os.path.dirname(os.path.abspath(__file__))
            uic.loadUi(os.path.join(dirname,'main.ui'), self)
    
            delegate = HTMLDelegate(self.lwOptions)
            self.lwOptions.setItemDelegate(delegate)
    
            for ordinal in ['first', 'second', 'third', 'fourth', 'fifth', 'sixth']:
                item = QtWidgets.QListWidgetItem('This is the <b>{}</b> word.'.format(ordinal))
                self.lwOptions.addItem(item)
    
    if __name__ == '__main__':
        import sys
        app = QtWidgets.QApplication(sys.argv)
        window = GUI()
        window.show()
        sys.exit(app.exec_())
    

    【讨论】:

    • 再次感谢您提供另一个完美的解决方案!
    • @eyllanesc 此示例是否可能仅涵盖 ForegroundRole 格式 - 如文本颜色和文本格式,但对 BackgroundRole 的背景颜色没有帮助?我尝试传递它

      foot

      但代表没有处理背景颜色。 ...我还注意到在 python 模型中使用 BackgroundRole 像这样: if role == QtCore.Qt.BackgroundRole: if True: return QtGui.QColor('red') 确实有效,同时尝试为类似的 ForegroundRole 失败。你能帮我看看为什么吗?交易
    猜你喜欢
    • 2016-05-25
    • 2022-01-20
    • 1970-01-01
    • 2014-03-12
    • 1970-01-01
    • 2018-03-03
    • 2013-02-10
    • 1970-01-01
    相关资源
    最近更新 更多