使用委托 (PySide/Qt/PyQt) 垂直居中项目的文本 [英] Vertically center item's text using a delegate (PySide/Qt/PyQt)

查看:43
本文介绍了使用委托 (PySide/Qt/PyQt) 垂直居中项目的文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 QTableView 的自定义委托,允许显示/编辑 html 字符串(使用 QTextDocument).下面有一个 SSCCE.

I have a custom delegate for a QTableView that allows for the display/editing of html strings (using a QTextDocument). There is a SSCCE below.

不幸的是,当我使用 paint() 显示文本时,它不是垂直居中,而是顶部对齐.例如,如果我将委托应用于第二列,而不是第一列,则表格如下所示:

Unfortunately, when I display the text using paint(), it is not vertically centered, but seems to top align. For instance, if I apply the delegate to the second column, but not the first, the table looks like this:

我的搜索没有发现任何有关如何以原则性方式从委托内部解决此问题的信息.手动将 5 添加到 option.rect.y() 可以在我的电脑上工作,但我不认为这是有原则的.

My search hasn't revealed anything on how to fix this from within the delegate in a principled way. Manually adding 5 to option.rect.y() works on my computer, but I don't consider that principled.

有没有办法让文本垂直居中?

Is there some way to center the text vertically?

SSCCE

from PySide import QtGui
import sys

class HtmlTable(QtGui.QTableView):
    def __init__(self, parent = None):    
        QtGui.QTableView.__init__(self)
        model = QtGui.QStandardItemModel()
        model.setHorizontalHeaderLabels(['Title', 'Summary'])
        item0 = [QtGui.QStandardItem('Infinite Jest'), QtGui.QStandardItem('Hello, <i>Hal</i>')]
        item00 = [QtGui.QStandardItem('Hamlet'), QtGui.QStandardItem('Best served <b>cold</b>')]
        model.appendRow(item0)
        model.appendRow(item00)          
        self.setModel(model)
        self.setItemDelegate(HtmlPainter(self))

class HtmlPainter(QtGui.QStyledItemDelegate):
    def __init__(self, parent=None):
        QtGui.QStyledItemDelegate.__init__(self, parent)
    def paint(self, painter, option, index):
        if index.column() == 1: 
            text = index.model().data(index) #default role is display
            palette = QtGui.QApplication.palette()
            document = QtGui.QTextDocument()
            document.setDefaultFont(option.font)
            #Set text (color depends on whether selected)
            if option.state & QtGui.QStyle.State_Selected:  
                displayString = "<font color={0}>{1}</font>".format(palette.highlightedText().color().name(), text) 
                document.setHtml(displayString)
            else:
                document.setHtml(text)
            #Set background color
            bgColor = palette.highlight().color() if (option.state & QtGui.QStyle.State_Selected)\
                     else palette.base().color()
            painter.save()
            painter.fillRect(option.rect, bgColor)
            painter.translate(option.rect.x(), option.rect.y())  #If I add +5 it works
            document.drawContents(painter)
            painter.restore()
        else:
            QtGui.QStyledItemDelegate.paint(self, painter, option, index)          


def main():
    app = QtGui.QApplication(sys.argv)
    myTable = HtmlTable()
    myTable.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

推荐答案

您应该使用 QTextDocument::setTextWidth 设置文档的宽度.这允许您确定文本高度并使用它来计算偏移:

You should set document's width using QTextDocument::setTextWidth. This allows you to determine text height and use it to calculate offset:

document.setTextWidth(option.rect.width())
offset_y = (option.rect.height() - document.size().height())/2
painter.translate(option.rect.x(), option.rect.y() + offset_y) 
document.drawContents(painter) 

设置文本宽度也是必要的,否则当列不够宽时文本不会被换行.

Setting text width is also necessary because otherwise the text would not be wrapped when column is not wide enough.

您可能需要重新实现 sizeHint 以根据文档大小计算首选宽度和高度.

You might want to reimplement sizeHint to calculate preferred width and height based on document size.

这篇关于使用委托 (PySide/Qt/PyQt) 垂直居中项目的文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆