mar*_*n2k 71 c++ qt qt4 qlabel
我使用QLabel向用户显示更大,动态变化的QPixmap的内容.根据可用空间,使这个标签更小/更大会很好.屏幕尺寸并不总是与QPixmap一样大.
如何修改QLabel QSizePolicy和sizeHint()QLabel以调整QPixmap的大小,同时保持原始QPixmap的宽高比?
我无法修改sizeHint()QLabel,设置minimumSize()为零无济于事.hasScaledContents()QLabel上的设置允许增长,但是打破了宽高比...
子类化QLabel确实有帮助,但是这个解决方案只为一个简单的问题添加了太多的代码......
任何聪明的提示如何在没有子类化的情况下完成此任务?
pne*_*zis 88
要更改标签大小,您可以为标签选择适当的大小策略,例如扩展或最小扩展.
您可以通过每次更改时保持其宽高比来缩放像素图:
QPixmap p; // load pixmap
// get label dimensions
int w = label->width();
int h = label->height();
// set a scaled pixmap to a w x h window keeping its aspect ratio
label->setPixmap(p.scaled(w,h,Qt::KeepAspectRatio));
Run Code Online (Sandbox Code Playgroud)
您应该在两个地方添加此代码:
resizeEvent包含标签的小部件中phy*_*att 29
我已经完善了这个遗漏的子类QLabel.它很棒,效果很好.
aspectratiopixmaplabel.h
#ifndef ASPECTRATIOPIXMAPLABEL_H
#define ASPECTRATIOPIXMAPLABEL_H
#include <QLabel>
#include <QPixmap>
#include <QResizeEvent>
class AspectRatioPixmapLabel : public QLabel
{
Q_OBJECT
public:
explicit AspectRatioPixmapLabel(QWidget *parent = 0);
virtual int heightForWidth( int width ) const;
virtual QSize sizeHint() const;
QPixmap scaledPixmap() const;
public slots:
void setPixmap ( const QPixmap & );
void resizeEvent(QResizeEvent *);
private:
QPixmap pix;
};
#endif // ASPECTRATIOPIXMAPLABEL_H
Run Code Online (Sandbox Code Playgroud)
aspectratiopixmaplabel.cpp
#include "aspectratiopixmaplabel.h"
//#include <QDebug>
AspectRatioPixmapLabel::AspectRatioPixmapLabel(QWidget *parent) :
QLabel(parent)
{
this->setMinimumSize(1,1);
setScaledContents(false);
}
void AspectRatioPixmapLabel::setPixmap ( const QPixmap & p)
{
pix = p;
QLabel::setPixmap(scaledPixmap());
}
int AspectRatioPixmapLabel::heightForWidth( int width ) const
{
return pix.isNull() ? this->height() : ((qreal)pix.height()*width)/pix.width();
}
QSize AspectRatioPixmapLabel::sizeHint() const
{
int w = this->width();
return QSize( w, heightForWidth(w) );
}
QPixmap AspectRatioPixmapLabel::scaledPixmap() const
{
return pix.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
}
void AspectRatioPixmapLabel::resizeEvent(QResizeEvent * e)
{
if(!pix.isNull())
QLabel::setPixmap(scaledPixmap());
}
Run Code Online (Sandbox Code Playgroud)
希望有所帮助!(更新resizeEvent,根据@ dmzl的回答)
Tim*_*mmm 12
我只是contentsMargin用来修复宽高比.
#pragma once
#include <QLabel>
class AspectRatioLabel : public QLabel
{
public:
explicit AspectRatioLabel(QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
~AspectRatioLabel();
public slots:
void setPixmap(const QPixmap& pm);
protected:
void resizeEvent(QResizeEvent* event) override;
private:
void updateMargins();
int pixmapWidth = 0;
int pixmapHeight = 0;
};
Run Code Online (Sandbox Code Playgroud)
#include "AspectRatioLabel.h"
AspectRatioLabel::AspectRatioLabel(QWidget* parent, Qt::WindowFlags f) : QLabel(parent, f)
{
}
AspectRatioLabel::~AspectRatioLabel()
{
}
void AspectRatioLabel::setPixmap(const QPixmap& pm)
{
pixmapWidth = pm.width();
pixmapHeight = pm.height();
updateMargins();
QLabel::setPixmap(pm);
}
void AspectRatioLabel::resizeEvent(QResizeEvent* event)
{
updateMargins();
QLabel::resizeEvent(event);
}
void AspectRatioLabel::updateMargins()
{
if (pixmapWidth <= 0 || pixmapHeight <= 0)
return;
int w = this->width();
int h = this->height();
if (w <= 0 || h <= 0)
return;
if (w * pixmapHeight > h * pixmapWidth)
{
int m = (w - (pixmapWidth * h / pixmapHeight)) / 2;
setContentsMargins(m, 0, m, 0);
}
else
{
int m = (h - (pixmapHeight * w / pixmapWidth)) / 2;
setContentsMargins(0, m, 0, m);
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止对我来说非常适合.别客气.
如果您的图像是资源或文件,则无需对任何内容进行子类化;image只需在标签的样式表中设置即可;它将缩放以适应标签,同时保持其纵横比,并将跟踪对标签所做的任何尺寸更改。您可以选择使用image-position将图像移动到边缘之一。
它不适合OP动态更新像素图的情况(我的意思是,您可以随时设置不同的资源,但它们仍然必须是资源),但如果您使用资源中的像素图,这是一个很好的方法。
样式表示例:
image: url(:/resource/path);
image-position: right center; /* optional: default is centered. */
Run Code Online (Sandbox Code Playgroud)
在代码中(例如):
QString stylesheet = "image:url(%1);image-position:right center;";
existingLabel->setStyleSheet(stylesheet.arg(":/resource/path"));
Run Code Online (Sandbox Code Playgroud)
或者您可以直接在设计器中设置样式表属性:
图标来源:Designspace Team via Flaticon
需要注意的是,它不会将图像缩放得更大,只会缩放得更小,因此,如果您希望图像增大,请确保图像大于您的尺寸范围(请注意,它可以支持 SVG,这可以提高质量)。
标签的大小可以像平常一样控制:使用样式表中的大小元素或使用标准布局和大小策略策略。
有关详细信息,请参阅文档。
这种风格从 Qt 早期就已经存在(位置是在 2007 年左右的 4.3 中添加的,但图像在那之前就已经存在了)。
改编自 Timmmm 到 PYQT5
from PyQt5.QtGui import QPixmap
from PyQt5.QtGui import QResizeEvent
from PyQt5.QtWidgets import QLabel
class Label(QLabel):
def __init__(self):
super(Label, self).__init__()
self.pixmap_width: int = 1
self.pixmapHeight: int = 1
def setPixmap(self, pm: QPixmap) -> None:
self.pixmap_width = pm.width()
self.pixmapHeight = pm.height()
self.updateMargins()
super(Label, self).setPixmap(pm)
def resizeEvent(self, a0: QResizeEvent) -> None:
self.updateMargins()
super(Label, self).resizeEvent(a0)
def updateMargins(self):
if self.pixmap() is None:
return
pixmapWidth = self.pixmap().width()
pixmapHeight = self.pixmap().height()
if pixmapWidth <= 0 or pixmapHeight <= 0:
return
w, h = self.width(), self.height()
if w <= 0 or h <= 0:
return
if w * pixmapHeight > h * pixmapWidth:
m = int((w - (pixmapWidth * h / pixmapHeight)) / 2)
self.setContentsMargins(m, 0, m, 0)
else:
m = int((h - (pixmapHeight * w / pixmapWidth)) / 2)
self.setContentsMargins(0, m, 0, m)
Run Code Online (Sandbox Code Playgroud)
我尝试使用phyatt的AspectRatioPixmapLabel课程,但遇到了一些问题:
QLabel::setPixmap(...)resizeEvent方法内部的调用,因为QLabel实际上是调用updateGeometryinside setPixmap,这可能会触发调整大小事件...heightForWidth似乎被包含的小部件(QScrollArea在我的情况下为a)所忽略,直到我开始为标签设置尺寸策略,显式调用policy.setHeightForWidth(true)QLabel的实现对minimumSizeHint()包含文本的标签起到了一些神奇的作用,但是始终将大小策略重置为默认策略,因此我不得不覆盖它就是说,这是我的解决方案。我发现,我可以只使用setScaledContents(true),让QLabel处理进行调整。当然,这取决于包含的小部件/布局heightForWidth。
Aspectratiopixmaplabel.h
#ifndef ASPECTRATIOPIXMAPLABEL_H
#define ASPECTRATIOPIXMAPLABEL_H
#include <QLabel>
#include <QPixmap>
class AspectRatioPixmapLabel : public QLabel
{
Q_OBJECT
public:
explicit AspectRatioPixmapLabel(const QPixmap &pixmap, QWidget *parent = 0);
virtual int heightForWidth(int width) const;
virtual bool hasHeightForWidth() { return true; }
virtual QSize sizeHint() const { return pixmap()->size(); }
virtual QSize minimumSizeHint() const { return QSize(0, 0); }
};
#endif // ASPECTRATIOPIXMAPLABEL_H
Run Code Online (Sandbox Code Playgroud)
Aspectratiopixmaplabel.cpp
#include "aspectratiopixmaplabel.h"
AspectRatioPixmapLabel::AspectRatioPixmapLabel(const QPixmap &pixmap, QWidget *parent) :
QLabel(parent)
{
QLabel::setPixmap(pixmap);
setScaledContents(true);
QSizePolicy policy(QSizePolicy::Maximum, QSizePolicy::Maximum);
policy.setHeightForWidth(true);
this->setSizePolicy(policy);
}
int AspectRatioPixmapLabel::heightForWidth(int width) const
{
if (width > pixmap()->width()) {
return pixmap()->height();
} else {
return ((qreal)pixmap()->height()*width)/pixmap()->width();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
84785 次 |
| 最近记录: |