如何在 Qt Widgets 中按比例显示图像作为 PreserveAspectFit

How to display image in ratio as PreserveAspectFit in Qt Widgets

在qml中,我可以简单地做到这一点

    Image {
        anchors.fill: parent
        source: "/path/to/coo/image"
        fillMode: Image.PreserveAspectFit
    }

我不想使用 QML,因为它与 JavaScript 有联系。我如何使用小部件执行此操作?

我尝试使用 QLabel,但它没有设置纵横比或填充模式的选项。我想我可以手动缩放像素图,然后将其设置为 QLabel,但这不会像 QML 那样反应(调整 window 大小时调整图像大小)。 Qt 中没有任何特定于图像的小部件可以执行此操作吗?

你可以简单地这样做:

QPixmap pixmap("background.png");
pixmap.scaled(pixmap.size(), Qt::KeepAspectRatio);

您可以随心所欲地操纵尺寸值。如果你愿意,你可以捕捉像素图所在的 QLabel 的大小。

一个可能的解决方案是使用 QGraphicsView、QGraphicsScene 和 QGraphicsPixmapItem:

#include <QApplication>
#include <QGraphicsPixmapItem>
#include <QGraphicsView>
#include <QPixmap>

class Viewer: public QGraphicsView{
public:
    Viewer(QWidget *parent = nullptr): QGraphicsView(parent){
        setScene(new QGraphicsScene(this));
        m_pixmapItem = scene()->addPixmap(QPixmap());
        setAlignment(Qt::AlignCenter);
    }
    QPixmap pixmap() const{
         return m_pixmapItem->pixmap();
    }
    void setPixmap(const QPixmap &newPixmap){
        m_pixmapItem->setPixmap(newPixmap);
        fitInView(m_pixmapItem, Qt::KeepAspectRatio);
    }
protected:
    void resizeEvent(QResizeEvent *event){
        QGraphicsView::resizeEvent(event);
        fitInView(m_pixmapItem, Qt::KeepAspectRatio);
    }
private:
    QGraphicsPixmapItem *m_pixmapItem;
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QPixmap pixmap(100, 200);
    pixmap.fill(Qt::green);

    Viewer w;
    w.resize(640, 480);
    w.setPixmap(pixmap);
    w.show();

    return a.exec();
}

Python版本:

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication, QGraphicsScene, QGraphicsView


class Viewer(QGraphicsView):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setScene(QGraphicsScene(self))
        self.m_pixmapItem = self.scene().addPixmap(QPixmap())
        self.setAlignment(Qt.AlignCenter)

    @property
    def pixmap(self):
        return self.m_pixmapItem.pixmap()

    @pixmap.setter
    def pixmap(self, newPixmap):
        self.m_pixmapItem.setPixmap(newPixmap)
        self.fitInView(self.m_pixmapItem, Qt.KeepAspectRatio)

    def resizeEvent(self, event):
        super().resizeEvent(event)
        self.fitInView(self.m_pixmapItem, Qt.KeepAspectRatio)


def main():
    import sys

    app = QApplication(sys.argv)

    pixmap = QPixmap(100, 200)
    pixmap.fill(Qt.green)

    w = Viewer()
    w.resize(640, 480)
    w.pixmap = pixmap
    w.show()

    sys.exit(app.exec_())


if __name__ == "__main__":
    main()
``