Skip to content

Instantly share code, notes, and snippets.

@EssGeeEich
Last active October 11, 2022 22:07
Show Gist options
  • Select an option

  • Save EssGeeEich/80b15ea5d5e9781dcf527f42c752b6ff to your computer and use it in GitHub Desktop.

Select an option

Save EssGeeEich/80b15ea5d5e9781dcf527f42c752b6ff to your computer and use it in GitHub Desktop.
A simple and fast QWidget that simply displays an image, scaling it down and keeping its aspect ratio, eventually aligning it to a preferred corner.
#include "qimagewidget.h"
#include <QPainter>
QImageWidget::QImageWidget(QWidget *parent, Qt::Alignment alignment)
: QWidget{parent},
m_alignment(alignment)
{}
QImage QImageWidget::image() const { return m_image; }
QPixmap QImageWidget::pixmap() const { return m_pixmap; }
void QImageWidget::setImage(QImage const& img) {
if(m_image == img)
return;
m_image = img;
m_pixmap = QPixmap::fromImage(m_image);
this->update();
}
void QImageWidget::setPixmap(QPixmap const& pixmap) {
m_pixmap = pixmap;
m_image = m_pixmap.toImage();
this->update();
}
void QImageWidget::setAlignment(Qt::Alignment alignment)
{
if(m_alignment == alignment)
return;
m_alignment = alignment;
this->update();
}
void QImageWidget::paintEvent(QPaintEvent* event)
{
QWidget::paintEvent(event);
if(m_pixmap.isNull())
return;
QRect clientRect = rect();
QSize targetSize = m_pixmap.size().scaled(clientRect.size(), Qt::KeepAspectRatio);
QRect drawRect = QRect(QPoint(0,0), targetSize);
switch(m_alignment & Qt::AlignHorizontal_Mask) {
case Qt::AlignLeft:
// The QRect is already left-aligned. Nothing to do.
break;
case Qt::AlignRight:
drawRect.moveRight(clientRect.right());
break;
case Qt::AlignHCenter:
default:
// Note: Do not use center().
// It seems that Qt might return a value that's off by 1.
drawRect.moveLeft(std::floor((clientRect.x() + clientRect.width()) * 0.5) - std::floor(targetSize.width() * 0.5));
break;
}
switch(m_alignment & Qt::AlignVertical_Mask) {
case Qt::AlignTop:
// The QRect is already top-aligned. Nothing to do.
break;
case Qt::AlignBottom:
drawRect.moveBottom(clientRect.bottom());
break;
case Qt::AlignHCenter:
default:
drawRect.moveTop(std::floor((clientRect.y() + clientRect.height()) * 0.5) - std::floor(targetSize.height() * 0.5));
break;
}
QPainter painter(this);
painter.drawPixmap(drawRect, m_pixmap);
}
#ifndef QIMAGEWIDGET_H
#define QIMAGEWIDGET_H
#include <QWidget>
class QImageWidget : public QWidget
{
Q_OBJECT
public:
explicit QImageWidget(QWidget *parent = nullptr, Qt::Alignment alignment = Qt::AlignCenter);
QImage image() const;
QPixmap pixmap() const;
Qt::Alignment alignment() const;
public slots:
void setImage(QImage const&);
void setPixmap(QPixmap const&);
void setAlignment(Qt::Alignment);
protected:
virtual void paintEvent(QPaintEvent*) override;
QImage m_image;
QPixmap m_pixmap;
Qt::Alignment m_alignment;
};
#endif // QIMAGEWIDGET_H
@EssGeeEich

Copy link
Copy Markdown
Author

I hate that such a widget is not available by default on Qt.
This is why the above code is available for everyone, with the following license terms:

This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.

In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

For more information, please refer to http://unlicense.org/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment