PyQt6中QDial调整QLabel字体大小遭函数默认值覆盖问题
问题:QDial调节QLabel字体大小无效,始终固定为14pt
开发QtWidgets界面时,尝试用QDial控件调整QLabel的字体大小,但无论怎么调节,QLabel的字体始终保持14pt。通过打印日志发现,每次操作QDial时,字体设置函数会被调用三次:第一次传入QDial的数值(比如29),但随后两次都会传入默认值14,直接覆盖了之前的设置。而使用QFontComboBox修改字体类型时,不会出现字号被覆盖的问题。
最小复现代码
import sys from PyQt6.QtWidgets import ( QDial, QFontComboBox, QLabel, QMainWindow, QWidget, QVBoxLayout, QApplication ) from PyQt6.QtGui import QFont class MainWindow(QMainWindow): def __init__(self): super().__init__() self.layout = QVBoxLayout() self.fontcomboboxWidget = QFontComboBox() self.fontcomboboxWidget.currentFontChanged.connect(self.label_font_set) self.labelWidget = QLabel() self.labelWidget.setText("Hello world!") dialWidget = QDial() dialWidget.setRange(8, 96) # 设置字体大小范围 dialWidget.setSingleStep(1) dialWidget.valueChanged.connect(self.dial_value_changed) self.label_font_set() # 初始化QLabel为14pt Segoe UI字体 # 注释掉这行也无法解决QDial的问题,点击QDial或QFontComboBox都会把字号重置为14 # 添加控件到布局 self.layout.addWidget(self.fontcomboboxWidget) self.layout.addWidget(self.labelWidget) self.layout.addWidget(dialWidget) self.widget = QWidget() self.widget.setLayout(self.layout) self.setCentralWidget(self.widget) def label_font_set(self, newFont = "Segoe UI", size = 14): print(f"Size is {size}") font = QFont(newFont) font.setPointSize(size) # 确保QLabel字体与QFontComboBox选择一致 self.labelWidget.setFont(font) self.fontcomboboxWidget.setCurrentFont(font) def dial_value_changed(self, number): self.label_font_set(size = number) app = QApplication(sys.argv) window = MainWindow() window.show() app.exec()
问题原因
问题出在label_font_set函数中的self.fontcomboboxWidget.setCurrentFont(font)语句:
- 当通过QDial调用
label_font_set设置字号后,执行这行代码会触发QFontComboBox的currentFontChanged信号 - 而该信号连接的正是
label_font_set函数,但QFontComboBox传递给槽函数的是不带字号信息的QFont对象(QFontComboBox仅管理字体家族) - 此时
label_font_set会使用默认参数size=14重新设置字体,直接覆盖了QDial设置的字号,导致字体大小回到14pt
解决方案:拆分字体设置逻辑
将字体类型和字体大小的设置拆分为两个独立函数,避免互相触发信号造成的覆盖问题,同时维护一个统一的当前字体对象,确保字体的家族和字号始终同步。
修改后的代码
import sys from PyQt6.QtWidgets import ( QDial, QFontComboBox, QLabel, QMainWindow, QWidget, QVBoxLayout, QApplication ) from PyQt6.QtGui import QFont class MainWindow(QMainWindow): def __init__(self): super().__init__() self.layout = QVBoxLayout() self.fontcomboboxWidget = QFontComboBox() # 连接字体类型变化到专门的处理函数 self.fontcomboboxWidget.currentFontChanged.connect(self.update_font_family) self.labelWidget = QLabel() self.labelWidget.setText("Hello world!") # 维护统一的当前字体对象,初始化为14pt Segoe UI self.current_font = QFont("Segoe UI", 14) self.labelWidget.setFont(self.current_font) self.fontcomboboxWidget.setCurrentFont(self.current_font) dialWidget = QDial() dialWidget.setRange(8, 96) dialWidget.setSingleStep(1) dialWidget.setValue(14) # 初始化QDial值与字体大小一致 # 连接字号变化到专门的处理函数 dialWidget.valueChanged.connect(self.update_font_size) # 添加控件到布局 self.layout.addWidget(self.fontcomboboxWidget) self.layout.addWidget(self.labelWidget) self.layout.addWidget(dialWidget) self.widget = QWidget() self.widget.setLayout(self.layout) self.setCentralWidget(self.widget) def update_font_family(self, new_font): # 仅修改字体家族,保留当前字号 self.current_font.setFamily(new_font.family()) self.labelWidget.setFont(self.current_font) def update_font_size(self, size): # 仅修改字号,保留当前字体家族 self.current_font.setPointSize(size) self.labelWidget.setFont(self.current_font) app = QApplication(sys.argv) window = MainWindow() window.show() app.exec()
方案说明
- 用
current_font变量统一管理QLabel的字体属性,确保字体家族和字号始终同步 - 字体类型变化时,仅修改
current_font的家族属性,不影响字号 - 字号变化时,仅修改
current_font的字号属性,不影响字体家族 - 避免了QFontComboBox信号触发时对字号的覆盖,同时保证QLabel与QFontComboBox的字体家族一致
内容的提问来源于stack exchange,提问作者Freerey
相关产品推荐
相关产品推荐

