QGraphicsTextItem中的文字对齐

时间:2023-03-09 00:19:59
QGraphicsTextItem中的文字对齐

QGraphicsTextItem类可以放到QGraphicsScene或者QGraphicsItem上,用来显示格式化的文本内容,如HTML,当然纯文本也可以显示。如果只是显示纯文本,可以使用QGraphicsSimpleTextItem类。

下面的内容都以QGraphicsTextItem作为例子。

这段代码展示了如何使用QGraphicsTextItem:

# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui

app = QtGui.QApplication(sys.argv)

view = QtGui.QGraphicsView()
scene = QtGui.QGraphicsScene(0, 0, 350, 250, view)
view.setScene(scene)

item0 = QtGui.QGraphicsTextItem()
item0.setPlainText('this is plain text')
scene.addItem(item0)
item0.setPos(50, 50)

item1 = QtGui.QGraphicsTextItem()
item1.setHtml('<strong>this is bold text with html strong tag</strong>')
scene.addItem(item1)
item1.setPos(50, 100)

item2 = QtGui.QGraphicsTextItem()
item2.setPlainText('this is the first line\nthis is the second line\nthis is the third line')
scene.addItem(item2)
item2.setPos(50, 150)

view.show()

sys.exit(app.exec_())
效果如下图:

QGraphicsTextItem中的文字对齐
可以看到内容是默认左对齐的,那么如何居中对齐或右对齐呢?我们首先想到的是使用HTML,HTML中居中对齐有两种方式,一种直接使用align="center",另一种使用css设置text-align: center;。

写成HTML:

<div align="center">this is the first line<br>this is the second line<br>this is the third line</div>
<br><br><br>
<div style="text-align: center;">this is the first line<br>this is the second line<br>this is the third line</div>
用浏览器查看效果如下:

QGraphicsTextItem中的文字对齐
在PyQt4中:

setHtml('<div align="center">this is the first line<br>this is the second line<br>this is the third line</div>')
setHtml('<div style="text-align: center;">this is the first line<br>this is the second line<br>this is the third line</div>')
很不幸,没有起作用:

QGraphicsTextItem中的文字对齐
此路不通,但是即便可行,这种方式还有个问题,当我们使用编辑模式修改QGraphicsTextItem的内容时,样式会遭到破坏。

我们使用另外一种方式,QGraphicsTextItem有个document (self)方法,返回一个QTextDocument对象,查看文档,可以发现QTextDocument可以通过QTextOption来设置文本属性。使用option.setAlignment(QtCore.Qt.AlignCenter)可以设置文本居中。

item = QtGui.QGraphicsTextItem()
document = item.document()
option = document.defaultTextOption()
option.setAlignment(QtCore.Qt.AlignCenter)
document.setDefaultTextOption(option)
item.setPlainText('this is the first line\nthis is the second line\nthis is the third line')
令人抓狂的是还是不管用。到底怎么回事?我们添加一行代码看看:

print document.textWidth()
打印结果是-1.0,这说明什么?说明document是没有宽度的,就很好理解了,没有宽度,就没有右边界,居中当然没法算了,右对齐也没法算,所以默认还是左对齐。通过设置宽度就可以解决这个问题。

item.setTextWidth(200)
大功告成,文字居中对齐了。但是还有问题,这个宽度200是我随便设置的,万一设成100就发现文字折行了。我们需要更完美的解决,进一步查看QTextDocument文档可以发现其提供了一个idealWidth (self)的方法,该方法返回了document的理想宽度。完整代码如下:

# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui

app = QtGui.QApplication(sys.argv)

view = QtGui.QGraphicsView()
view.setWindowTitle('QGraphicsTextItem')
scene = QtGui.QGraphicsScene(0, 0, 350, 350, view)
view.setScene(scene)

y = 50

for align in (QtCore.Qt.AlignLeft, QtCore.Qt.AlignCenter, QtCore.Qt.AlignRight):
item = QtGui.QGraphicsTextItem()
document = item.document()
option = document.defaultTextOption()
option.setAlignment(align)
document.setDefaultTextOption(option)
item.setPlainText('this is the first line\nthis is the second line\nthis is the third line')
item.setTextWidth(document.idealWidth())
scene.addItem(item)
item.setPos(50, y)

y += 100

view.show()

sys.exit(app.exec_())
效果如下图:

QGraphicsTextItem中的文字对齐