我正在尝试使用PyQt5创建字符映射可视化工具。使用fontTools库,我可以提取给定ttf文件中支持的UNICODE代码点。然后使用QPainter.drawText
在标签上绘制字形。标签存储在QGridLayout
中,布局存储在QScrollArea
一切正常,除非我尝试滚动。每当我尝试太快滚动时,绘制的图像就会重叠。看起来像这样。
窗口失去焦点时,标签会正确重绘。
这是我到目前为止的MWE。
import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFontDatabase, QFont, QColor, QPainter
from fontTools.ttLib import TTFont
class App(QWidget):
def __init__(self):
super().__init__()
self.fileName = "mukti.ttf" #the ttf file is located in the same path as the script
self.initUI()
def initUI(self):
self.setWindowTitle("Glyph Viewer")
self.setFixedSize(640, 480)
self.move(100, 100)
vBox = QtWidgets.QVBoxLayout()
self.glyphView = GlyphView()
vBox.addWidget(self.glyphView)
self.setLayout(vBox)
self.showGlyphs()
self.show()
def showGlyphs(self):
#Using the fontTools libray, the unicode blocks are obtained from the ttf file
font = TTFont(self.fileName)
charMaps = list()
for cmap in font['cmap'].tables:
charMaps.append(cmap.cmap)
charMap = charMaps[0]
fontDB = QFontDatabase()
fontID = fontDB.addApplicationFont("mukti.ttf")
fonts = fontDB.applicationFontFamilies(fontID)
qFont = QFont(fonts[0])
qFont.setPointSize(28)
self.glyphView.populateGrid(charMap, qFont)
class GlyphView(QtWidgets.QScrollArea):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.setWidgetResizable(True)
def populateGrid(self, charMap, qFont):
glyphArea = QtWidgets.QWidget(self)
gridLayout = QtWidgets.QGridLayout()
glyphArea.setLayout(gridLayout)
row, col = 1, 1
for char in charMap:
uni = charMap[char]
gridLayout.addWidget(Glyph(qFont, chr(char)), row, col)
if not col % 4:
col = 1
row += 1
else:
col += 1
self.setWidget(glyphArea)
class Glyph(QtWidgets.QLabel):
def __init__(self, font, char):
super().__init__()
self.font = font
self.char = char
self.initUI()
def initUI(self):
self.setFixedSize(48, 48)
self.setToolTip(self.char)
def paintEvent(self, event):
qp = QPainter(self)
qp.setBrush(QColor(0,0,0))
qp.drawRect(0, 0, 48, 48)
qp.setFont(self.font)
qp.setPen(QColor(255, 255, 255))
qp.drawText(event.rect(), Qt.AlignCenter, self.char)
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
我不确定是什么原因造成的。任何帮助表示赞赏!
答案 0 :(得分:2)
QPaintEvent
方法为我们提供了一个属于QRect
的对象,该对象通过rect()
方法提供了一个QRect
,即QRect
是区域这是当前可见的信息,并且该信息可以用于优化绘画,例如,假设我们有一个小部件以多行显示文本,如果文本很大,那么几行看起来就会如此,因此绘画全部都是浪费资源,因此通过使用上述event.rect()
进行适当的计算,我们可以得到这些线条并用很少的资源画出那部分。在this answer中,展示了一个使用event.rect()的示例。
在您的情况下,无需使用self.rect()
,因为您将在小部件小部件的一部分中绘制文本。您应该使用的是def paintEvent(self, event):
qp = QPainter(self)
qp.setBrush(QColor(0,0,0))
qp.drawRect(0, 0, 48, 48)
qp.setFont(self.font())
qp.setPen(QColor(255, 255, 255))
# change event.rect() to self.rect()
qp.drawText(self.rect(), Qt.AlignCenter, self.text())
:
paintEvent()
我还认为没有必要覆盖QLabel
方法,因为您可以直接指向class Glyph(QtWidgets.QLabel):
def __init__(self, font, char):
super().__init__(font=font, text=char, alignment=Qt.AlignCenter, toolTip=char)
的字体,文本和对齐方式:
{{1}}