如何让文字填满 QLabel 的所有空间? [英] How to make the text fill all the QLabel's space?

查看:87
本文介绍了如何让文字填满 QLabel 的所有空间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究 PyQt5 项目,但也很乐意阅读 C++/Qt 答案,因为 C++ 解决方案也可能适用于 Python.

I am working on a PyQt5 project, but would be happy to read C++/Qt answer as well, because C++ solutions may work on Python too.

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

I have a MainWindow with a horizontal layout, and a QLabel in it.

我的 QLabel 的大小策略是扩展",因此我的所有窗口都被 QLabel 填充.

My QLabel's size Policy is "Expanding", therefore all my window is filled by the QLabel.

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

However, the text displayed by my QLabel does not change its size. I would like the text to grow when the window grows, and be as big as possible, in the limit of the QLabel size.

我听说过 QWidget::adjustSize() 但不知道如何使用它.QtDesigner 上我的 QLabel 的选项 scaledContents 没有任何作用,所以我想它只在使用 pixmap 时有用.

I have heard of QWidget::adjustSize() but could not figure out how to use it. The option scaledContents for my QLabel on QtDesigner does not do anything, so I guess it is only useful for when using pixmap.

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

For the moment, my solution is to reimplement the resizeEvent() method of my window and change the font size of my label with setFont(). But I think that there must be an easier solution. Moreover, my resizeEvent() method is not very good because I make a linear relation between myWindowWidth* myWindowHeight and myTextFontSize, therefore when only myWindowWidth increase, myTextFontSize increases and forces myWindowHeight to increase, which is bad.

推荐答案

这是一个可能指向解决方案的快速草图.事件过滤器可以安装在任何标签上,以使其文本填充可用空间,而不是从标签派生.过滤器使用现有的 scaledContents 属性,并将其适用于文本内容.

This is a quick sketch that might point to a solution. Instead of deriving from a label, an event filter can be installed on any label to make its text fill the available space. The filter uses the existing scaledContents property, and extends its applicability to text content.

使用牛顿算法调整标签的字体大小以填充可用空间.需要进行一些调整才能使其与启用自动换行的标签一起使用;字体大小不应超过适合的大小.

The label's font size is adjusted using Newton's algorithm to fill the available space. Some adjustments would be needed to make it work with labels that enable word wrap; the font size should then never overshoot what fits.

// 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"

这篇关于如何让文字填满 QLabel 的所有空间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆