如何使文本填满QLabel的所有空间?

时间:2016-04-12 13:45:14

标签: qt pyqt qlabel

我正在研究PyQt5项目,但也很乐意阅读C ++ / Qt的答案,因为C ++解决方案也可以在Python上运行。

我有一个水平布局的MainWindow,里面有一个QLabel。

我的QLabel规模政策是"扩展"因此我的所有窗口都由QLabel填充。

但是,我的QLabel显示的文字不会改变其大小。我希望文本在窗口增长时增长,并且尽可能大,在QLabel大小的限制内。

我听说过var result = output[4]; // yields "price1" ,但无法弄清楚如何使用它。 QtDesel上的QLabel选项String.Split()没有做任何事情,所以我猜它只对使用pixmap有用。

目前,我的解决方案是重新实现窗口的QWidget::adjustSize()方法,并使用scaledContents更改标签的字体大小。但我认为必须有一个更容易的解决方案。此外,我的resizeEvent()方法不是很好,因为我在setFont()resizeEvent()之间建立了线性关系,因此只有myWindowWidth* myWindowHeight增加时,myTextFontSize增加并强制myWindowWidth增加,这是不好的。

1 个答案:

答案 0 :(得分:2)

这是一个可能指向解决方案的快速草图。可以在任何标签上安装事件过滤器,使其文本填充可用空间,而不是从标签派生。过滤器使用现有的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"