这样的功能可以很容易地实现QFontMetricsF
from PyQt5 import QtCore, QtGui, QtWidgets
import math
def drawText(painter, rect, text):
metrics = QtGui.QFontMetricsF(painter.font())
space = metrics.horizontalAdvance(" ")
width = rect.width()
def lineWidth(line):
return sum([word[1] for word in line]) + space * (len(line) - 1)
def canFit(line, word):
return lineWidth(line + [word]) < width
def forceSplit(word):
charSize = [metrics.horizontalAdvance(c) for c in word[0]]
for i in reversed(range(1,len(charSize))):
if sum(charSize[:i]) < width:
return [(word, metrics.horizontalAdvance(word)) for word in [word[0][:i], word[0][i:]]]
queue = [(word, metrics.horizontalAdvance(word)) for word in text.split(" ")]
lines = []
line = []
while len(queue) > 0:
word = queue.pop(0)
if canFit(line, word):
line.append(word)
else:
if len(line) == 0:
word1, word2 = forceSplit(word)
line.append(word1)
lines.append(line)
line = []
queue.insert(0, word2)
else:
lines.append(line)
line = []
queue.insert(0, word)
if len(line) > 0:
lines.append(line)
line = []
painter.save()
painter.setClipRect(rect)
x = rect.x()
y = rect.y() + metrics.height()
for line in lines:
text = " ".join([word[0] for word in line])
painter.drawText(int(x), int(y), text)
y += metrics.leading() + metrics.height()
painter.restore()
def replaceSomeSpaces(text, n):
res = []
for i,word in enumerate(text.split(" ")):
res.append(word)
if (i % n) == 0:
res.append(" ")
else:
res.append("_")
return "".join(res)
class Widget(QtWidgets.QWidget):
def __init__(self, parent = None):
super().__init__(parent)
self._text = None
def setText(self, text):
self._text = text
def paintEvent(self, event):
if self._text is None:
return
painter = QtGui.QPainter(self)
rect = self.rect()
# test clipping
# rect.setHeight(rect.height() / 2)
drawText(painter, rect, self._text)
def sizeHint(self):
return QtCore.QSize(200,200)
if __name__ == "__main__":
app = QtWidgets.QApplication([])
lorem = "Lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua"
widget = Widget()
widget.setFont(QtGui.QFont("Arial", 12))
widget.setText(replaceSomeSpaces(lorem, 3))
widget.show()
app.exec()