我正在研究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
增加,这是不好的。
答案 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"