Skip to main content
 首页 » 编程设计

python之在 PyQt 中将 Label 字体大小与布局同步

2025年05月04日45del

通过信号/插槽更改标签的字体大小以匹配其包含的布局大小的具体方法是什么?

请您参考如下方法:

下面是针对 QLabel 的解决方案,派生自此处发布的解决方案:https://forum.qt.io/topic/36088/automatically-scale-text-in-qlabels/5 .

这包括重新实现 resizeEvent 方法,其中 QLabel 的字体大小根据其 contentRect 的大小更新。请注意,Qlabel 的 sizePolicy 必须设置为 Ignored 才能正常工作。

import sys 
from PyQt4 import QtGui      
 
class myQLabel(QtGui.QLabel): 
    def __init__(self, *args, **kargs): 
        super(myQLabel, self).__init__(*args, **kargs) 
 
        self.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Ignored, 
                                             QtGui.QSizePolicy.Ignored))   
 
        self.setMinSize(14) 
 
    def setMinSize(self, minfs):         
 
        f = self.font() 
        f.setPixelSize(minfs) 
        br = QtGui.QFontMetrics(f).boundingRect(self.text()) 
 
        self.setMinimumSize(br.width(), br.height()) 
 
    def resizeEvent(self, event): 
        super(myQLabel, self).resizeEvent(event) 
 
        if not self.text(): 
            return 
 
        #--- fetch current parameters ---- 
 
        f = self.font() 
        cr = self.contentsRect() 
 
        #--- find the font size that fits the contentsRect --- 
 
        fs = 1                     
        while True: 
 
            f.setPixelSize(fs) 
            br =  QtGui.QFontMetrics(f).boundingRect(self.text()) 
 
            if br.height() <= cr.height() and br.width() <= cr.width(): 
                fs += 1 
            else: 
                f.setPixelSize(max(fs - 1, 1)) # backtrack 
                break   
 
        #--- update font size --- 
 
        self.setFont(f)      
 
 
class myApplication(QtGui.QWidget): 
    def __init__(self, parent=None): 
        super(myApplication, self).__init__(parent) 
 
        #---- Prepare a Layout ---- 
 
        grid = QtGui.QGridLayout()   
 
        for i in range(3): 
            grid.addWidget(myQLabel('some text'), i, 0)   
            grid.setRowStretch(i, i+1) 
            grid.setRowMinimumHeight(i, 25) 
 
        self.setLayout(grid) 
        self.resize(500, 300) 
 
 
if __name__ == '__main__': 
 
    app = QtGui.QApplication(sys.argv) 
 
    instance = myApplication()   
    instance.show()     
 
    sys.exit(app.exec_()) 

结果是:

更新 - resizeEvent 的优化:

下面是 resizeEvent 方法的优化版本,应该会产生更好的性能。它大大减少了找到最佳字体大小值所需的迭代次数。不过我还没有对其进行广泛的测试。

def resizeEvent(self, event): 
    super(myQLabel, self).resizeEvent(event)         
 
    if not self.text(): 
        return 
 
    #--- fetch current parameters ---- 
 
    f = self.font() 
    cr = self.contentsRect() 
 
    #--- iterate to find the font size that fits the contentsRect --- 
 
    dw = event.size().width() - event.oldSize().width()   # width change 
    dh = event.size().height() - event.oldSize().height() # height change 
 
    fs = max(f.pixelSize(), 1)         
    while True: 
 
        f.setPixelSize(fs) 
        br =  QtGui.QFontMetrics(f).boundingRect(self.text()) 
 
        if dw >= 0 and dh >= 0: # label is expanding 
 
            if br.height() <= cr.height() and br.width() <= cr.width(): 
                fs += 1 
            else: 
                f.setPixelSize(max(fs - 1, 1)) # backtrack 
                break                     
 
        else: # label is shrinking 
 
            if br.height() > cr.height() or br.width() > cr.width(): 
                fs -= 1 
            else: 
                break 
 
        if fs < 1: break 
 
    #--- update font size ---            
 
    self.setFont(f)