Qt:调整包含 QPixmap 的 QLabel 的大小,同时保持其纵横比

新手上路,请多包涵

我使用 QLabel 向用户显示更大、动态变化的 QPixmap 的内容。根据可用空间使这个标签更小/更大会很好。屏幕尺寸并不总是像 QPixmap 一样大。

如何修改 QLabel 的 QSizePolicysizeHint() 以调整 QPixmap 的大小,同时保持原始 QPixmap 的纵横比?

我无法修改 QLabel 的 sizeHint() ,将 minimumSize() 设置为零无济于事。在 QLabel 上设置 hasScaledContents() 允许增长,但会破坏纵横比…

子类化 QLabel 确实有帮助,但是这个解决方案为一个简单的问题添加了太多代码……

任何聪明的提示如何在 没有 子类化的情况下完成这个?

原文由 marvin2k 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.5k
2 个回答

为了更改标签尺寸,您可以为标签选择适当的尺寸策略,例如展开或最小展开。

您可以通过在每次更改时保持其纵横比来缩放像素图:

 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));

您应该在两个地方添加此代码:

  • 当像素图更新时
  • 在包含标签的小部件的 resizeEvent

原文由 pnezis 发布,翻译遵循 CC BY-SA 3.0 许可协议

这是@phyatt 类到 PySide2 的端口。

除了移植之外,我在 resizeEvent 中添加了一个额外的对齐,以便使新调整大小的图像在可用空间中正确定位。

 from typing import Union

from PySide2.QtCore import QSize, Qt
from PySide2.QtGui import QPixmap, QResizeEvent
from PySide2.QtWidgets import QLabel, QWidget

class QResizingPixmapLabel(QLabel):
    def __init__(self, parent: Union[QWidget, None] = ...):
        super().__init__(parent)
        self.setMinimumSize(1,1)
        self.setScaledContents(False)
        self._pixmap: Union[QPixmap, None] = None

    def heightForWidth(self, width:int) -> int:
        if self._pixmap is None:
            return self.height()
        else:
            return self._pixmap.height() * width / self._pixmap.width()

    def scaledPixmap(self) -> QPixmap:
        scaled = self._pixmap.scaled(
            self.size() * self.devicePixelRatioF(),
            Qt.KeepAspectRatio,
            Qt.SmoothTransformation
        )
        scaled.setDevicePixelRatio(self.devicePixelRatioF());
        return scaled;

    def setPixmap(self, pixmap: QPixmap) -> None:
        self._pixmap = pixmap
        super().setPixmap(pixmap)

    def sizeHint(self) -> QSize:
        width = self.width()
        return QSize(width, self.heightForWidth(width))

    def resizeEvent(self, event: QResizeEvent) -> None:
        if self._pixmap is not None:
            super().setPixmap(self.scaledPixmap())
            self.setAlignment(Qt.AlignCenter)

原文由 iblanco 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题