在PyQt中将Label fontsize与布局同步

时间:2015-04-24 16:14:02

标签: python python-3.x pyqt pyqt4

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

1 个答案:

答案 0 :(得分:4)

以下是针对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_())

结果是:

enter image description here

更新 - 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)