2016-04-12 76 views
1

我正在研究一個PyQt5項目,但也很樂意閱讀C++/Qt的答案,因爲C++解決方案也可能在Python上工作。如何讓文字填充所有QLabel的空間?

我有一個水平佈局的MainWindow和一個QLabel。

我的QLabel的尺寸政策是「展開」,因此我所有的窗口都由QLabel填充。

但是,由我的QLabel顯示的文本不會更改其大小。我希望在窗口增長時文本會增長,並且儘可能大,只限於QLabel大小。我聽說QWidget::adjustSize(),但無法弄清楚如何使用它。 QtDesigner上QLabel的選項scaledContents沒有任何作用,所以我想這隻適用於使用pixmap。

目前,我的解決方案是重新實現我的窗口的resizeEvent()方法,並更改我的標籤的字體大小爲setFont()。但我認爲必須有一個更簡單的解決方案。此外,我的方法不是很好,因爲我在myWindowWidth* myWindowHeightmyTextFontSize之間做了線性關係,因此當只有myWindowWidth增加時,myTextFontSize增加,迫使myWindowHeight增加,這是不好的。

回答

1

這是一個可能指向解決方案的快速草圖。事件過濾器可以安裝在任何標籤上,以使其文本填充可用空間,而不是從標籤派生。該過濾器使用現有的scaledContents屬性,並將其適用範圍擴展到文本內容。

使用牛頓算法調整標籤的字體大小以填充可用空間。需要進行一些調整才能使其能夠使用自動換行的標籤;字體大小不應超過適合的字體大小。

// https://github.com/KubaO/stackoverflown/tree/master/questions/label-text-size-36575192 
#include <QtWidgets> 

class LabelStretcher : public QObject { 
    Q_OBJECT 
public: 
    LabelStretcher(QObject * parent = 0) : QObject(parent) { 
     apply(qobject_cast<QLabel*>(parent)); 
    } 
    void apply(QLabel * label) { if (label) label->installEventFilter(this); } 
protected: 
    bool eventFilter(QObject * obj, QEvent * ev) Q_DECL_OVERRIDE { 
     if (ev->type() != QEvent::Resize) return false; 
     auto label = qobject_cast<QLabel*>(obj); 
     if (!label || label->text().isEmpty() || !label->hasScaledContents()) return false; 
     qDebug() << "pre: " << label->minimumSizeHint() << label->sizeHint() << label->size(); 

     static auto dSize = [](const QSize & inner, const QSize & outer) -> int { 
     auto dy = inner.height() - outer.height(); 
     auto dx = inner.width() - outer.width(); 
     return std::max(dx, dy); 
     }; 
     static auto f = [](qreal fontSize, QLabel * label) -> qreal { 
     auto font = label->font(); 
     font.setPointSizeF(fontSize); 
     label->setFont(font); 
     auto d = dSize(label->sizeHint(), label->size()); 
     qDebug() << "f:" << fontSize << "d" << d; 
     return d; 
     }; 
     static auto df = [](qreal fontSize, QLabel * label) -> qreal { 
     if (fontSize < 1.0) fontSize = 1.0; 
     return f(fontSize + 0.5, label) - f(fontSize - 0.5, label); 
     }; 

     // Newton's method 
     auto font = label->font(); 
     auto fontSize = font.pointSizeF(); 
     int i; 
     for (i = 0; i < 5; ++i) { 
     auto d = df(fontSize, label); 
     qDebug() << "d:" << d; 
     if (d < 0.1) break; 
     fontSize -= f(fontSize, label)/d; 
     } 
     font.setPointSizeF(fontSize); 
     label->setFont(font); 
     qDebug() << "post:" << i << label->minimumSizeHint() << label->sizeHint() << label->size(); 
     return false; 
    } 
}; 

int main(int argc, char ** argv) { 
    QApplication app{argc, argv}; 
    QLabel label{"Hello There!"}; 
    label.setScaledContents(true); 
    label.show(); 
    LabelStretcher stretch(&label); 
    return app.exec(); 
} 

#include "main.moc" 
相關問題