2

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

这是我到目前为止所拥有的:

主界面

<?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>

测试.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语法?

4

1 回答 1

4

Qt 默认不使用这些角色>= 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_())

在此处输入图像描述

于 2018-12-01T15:28:04.140 回答