废话
本案例显示一个字符数组,用户可以通过点击在行编辑内键入文本。行编辑的内容可以随后拷贝进剪贴板,并粘贴到其他应用。这类工具的目的,是允许用户键入那些难以找到或在键盘定位的字符。
该案例包含以下类:
- CharacterWidget类显示用当前字体和风格下的字符
- MainWindow类提供一个标准的主窗口,包括字体风格信息、字符映射图像、行编辑和一个可以提交文本到剪贴板的按钮
定义CharacterWidget类
- CharacterWidget用来显示在用户指定字体和风格下的字符集,为了灵活性,我们子类化QWidget,并只重写基础渲染和交互特征的函数。
- 该部件不需要包含其他部件,所以它必须提供自有的sizeHint(),来让内容正确显示。
- 我们重写paintEvent()来绘制自定义内容,同样重写mousePressEvent()用来允许用户与部件交互。
- updateFont()和updateStyle()槽,当用户在应用内更改设置时,用来更新部件内字符的字体和风格。
- 该类定义了characterSelected()信号,当用户在部件内选择了一个字符,会通知应用的其他部分。
- 出于习惯,不见提供了一个工具提示,用来显示当前字符的值。我们重写了mouseMoveEvent()事件处理程序,并定义了showToolTip()来实现这个特性。
- columns、displayFont和currentKey用来记录显示的列数、当前字体和部件内当前高亮的字符
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
import unicodedata
class CharacterWidget(QWidget):
characterSelected = pyqtSignal(str)
def __init__(self):
super(CharacterWidget, self).__init__()
self.displayFont = QFont()
self.squareSize = int(24)
self.columns = int(16)
self.lastKey = int(-1)
self.setMouseTracking(True)
- 初始化当前键值为-1,表明没有字符会在初始状态被选择。开启鼠标跟踪来允许我们跟踪穿过部件的光标移动。
def updateFont(self, font):
self.displayFont.setFamily(font.family())
self.squareSize = max(24, QFontMetrics(self.displayFont).xHeight() * 3)
self.adjustSize()
self.update()
def updateSize(self, fontSize):
self.displayFont.setPointSize(int(fontSize))
self.squareSize = max(24, QFontMetrics(self.displayFont).xHeight() * 3)
self.adjustSize()
self.update()
def updateStyle(self, fontStyle):
fontDatabase = QFontDatabase()
oldStrategy = self.displayFont.styleStrategy()
self.displayFont = fontDatabase.font(self.displayFont.family(), fontStyle, self.displayFont.pointSize())
self.displayFont.setStyleStrategy(oldStrategy)
self.squareSize = max(24, QFontMetrics(self.displayFont).xHeight() * 3)
self.adjustSize()
self.update()
def updateFontMerging(self, enable):
if enable:
self.displayFont.setStyleStrategy(QFont.PreferDefault)
else:
self.displayFont.setStyleStrategy(QFont.NoFontMerging)
self.adjustSize()
self.update()
- 以上四个方法允许设置字体、尺寸、样式和字体合并,最后调用update()进行修改。
def sizeHint(self):
return QSize(self.columns*self.squareSize, (65536/self.columns)*self.squareSize)
- 设置固定的sizeHint()
def paintEvent(self, QPaintEvent):
painter = QPainter()
painter.begin(self)
painter.fillRect(QPaintEvent.rect(), QBrush(Qt.white))
painter.setFont(self.displayFont)
redrawRect = QPaintEvent.rect()
beginRow = int(redrawRect.top()/self.squareSize)
endRow = int(redrawRect.bottom()/self.squareSize)
beginColumn = int(redrawRect.left()/self.squareSize)
endColumn = int(redrawRect.right()/self.squareSize)
painter.setPen(QPen(Qt.gray))
for i in range(beginRow, endRow+1):
for j in range(beginColumn, endColumn+1):
painter.drawRect(j*self.squareSize, i*self.squareSize, self.squareSize, self.squareSize)
fontMetrics = QFontMetrics(self.displayFont)
painter.setPen(QPen(Qt.black))
for r in range(beginRow, endRow+1):