In qml, I can simply do this
Image {
anchors.fill: parent
source: "/path/to/coo/image"
fillMode: Image.PreserveAspectFit
}
I don't want to use QML due to its ties with JavaScript. How can I do this with Widgets ?
I tried using QLabel but it has no option to set aspect ratio or fillMode. I think I can manually scale the pixmap and then set it to QLabel but that wont be reactive (resize image when window is resized) like QML. Isn't there any image specefic widget in Qt to do this ?
A possible solution is to use QGraphicsView, QGraphicsScene and 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 version:
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()
``