PyQt5开发诺基亚T9键盘:在QPushButton上方添加垂直布局的两个QLabel
解决PyQt5中诺基亚T9键盘按钮多行不同字号文本的问题
要实现T9键盘按钮的数字与字母分两行、不同字号显示,核心思路是将QPushButton作为容器,内部嵌套垂直布局放置两个QLabel,分别控制数字和字母的样式。以下是具体实现方案:
核心实现步骤
- 自定义继承自
QPushButton的按钮类,在按钮内部创建QVBoxLayout; - 向布局中添加两个
QLabel,分别显示数字和字母,单独设置字体大小; - 将自定义按钮整合到键盘的行列布局中。
完整代码示例
from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton, QVBoxLayout, QHBoxLayout, QLabel, QSizePolicy) from PyQt5.QtGui import QFont from PyQt5.QtCore import Qt import sys class T9Button(QPushButton): def __init__(self, number, letters, parent=None): super().__init__(parent) # 初始化按钮内部的垂直布局 inner_layout = QVBoxLayout(self) inner_layout.setContentsMargins(4, 4, 4, 4) # 调整内边距,避免文本紧贴按钮边缘 inner_layout.setSpacing(2) # 数字与字母标签的间距 # 数字标签:字号更大、加粗 num_label = QLabel(number) num_font = QFont() num_font.setPointSize(16) num_font.setBold(True) num_label.setFont(num_font) num_label.setAlignment(Qt.AlignCenter) # 字母标签:字号较小 letter_label = QLabel(letters) letter_font = QFont() letter_font.setPointSize(10) letter_label.setFont(letter_font) letter_label.setAlignment(Qt.AlignCenter) # 将标签添加到布局 inner_layout.addWidget(num_label) inner_layout.addWidget(letter_label) # 设置按钮自适应缩放 self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) class T9Keyboard(QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): self.setWindowTitle("诺基亚T9屏幕键盘") main_layout = QVBoxLayout(self) main_layout.setSpacing(8) main_layout.setContentsMargins(10, 10, 10, 10) # 构建键盘行布局 row1 = QHBoxLayout() row1.addWidget(T9Button("1", ".?!")) row1.addWidget(T9Button("2", "ABC")) row1.addWidget(T9Button("3", "DEF")) main_layout.addLayout(row1) row2 = QHBoxLayout() row2.addWidget(T9Button("4", "GHI")) row2.addWidget(T9Button("5", "JKL")) row2.addWidget(T9Button("6", "MNO")) main_layout.addLayout(row2) row3 = QHBoxLayout() row3.addWidget(T9Button("7", "PQRS")) row3.addWidget(T9Button("8", "TUV")) row3.addWidget(T9Button("9", "WXYZ")) main_layout.addLayout(row3) row4 = QHBoxLayout() row4.addWidget(T9Button("*", "Shift")) row4.addWidget(T9Button("0", "空格")) row4.addWidget(T9Button("#", "删除")) main_layout.addLayout(row4) self.resize(320, 400) if __name__ == "__main__": app = QApplication(sys.argv) keyboard = T9Keyboard() keyboard.show() sys.exit(app.exec_())
为什么之前的方法无效?
- QStackedWidget:它的作用是切换显示不同组件,同一时间仅能展示一个子组件,完全不适合实现两行文本叠加显示的需求;
- 直接使用QVBoxLayout未生效:如果只是创建布局但未将其设置为按钮的内部布局(即未把布局的父组件设为按钮),或者没有调整按钮的布局属性,布局会无法正常渲染。
额外优化建议
- 可根据需求修改标签的字体颜色、按钮的样式(如背景色、边框);
- 若需要处理按钮点击事件,可在
T9Button类中直接绑定clicked信号,或重写mousePressEvent方法; - 调整
setContentsMargins和setSpacing的值,优化文本与按钮边缘的间距。
内容的提问来源于stack exchange,提问作者Teodor Flykt
相关产品推荐
相关产品推荐

