简体   繁体   中英

How to draw QImage on QScrollArea? Did this, but have some minor problems QPainter::begin: Widget painting can only begin as a result of a paintEvent

Ok, so here's what I want to accomplish: I want to draw QImage so the window would have scroll bars in case of the image turned out to be too big. For now one, I have sth like this:

#include "imagewidget.h"
#include <QImage>
#include <QPainter>
#include <QGridLayout>
#include <QLabel>

ImageWidget::ImageWidget(QWidget* parent)
    : QWidget(parent)
{
    m_image = QImage();

    scrollArea = new QScrollArea(this);

    QGridLayout *gridLayout = new QGridLayout(this);
    imgDisplayLabel = new QLabel(this);
    imgDisplayLabel->setPixmap(QPixmap::fromImage(m_image));
    imgDisplayLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
    imgDisplayLabel->setScaledContents(true);
    imgDisplayLabel->adjustSize();

    scrollArea->setWidget(imgDisplayLabel);

    gridLayout->addWidget(scrollArea,0,0);
    setLayout(gridLayout);

}

void ImageWidget::paintEvent(QPaintEvent* event)
{

    QPainter paint(this);
    if(!m_image.isNull())
        paint.drawImage(0,0, m_image);

    imgDisplayLabel->setPixmap(QPixmap::fromImage(m_image));
    imgDisplayLabel->adjustSize();
    imgDisplayLabel->setScaledContents(true);
}

void ImageWidget::setImage(QImage im)
{
    m_image = im;
    update();
}

void ImageWidget::removeImage()
{
    m_image = QImage();
    update();
}

However, it does not give me the effect that I want to have:

在此处输入图片说明

When I change QPainter paint(this); to QPainter paint(scrollArea); I have the error message (or, it's the warning I guess): QPainter::begin: Widget painting can only begin as a result of a paintEvent but I'm able to run the application, and open / close images. So, the program actually works with this, but it the error message bothers me and I would like to know how to get rid of it. With this only one changed line from the above src code app works and displays images as it should:

在此处输入图片说明

Question is, where do you want to paint: on ImageWidget , on imgDisplayLabel , or on scrollArea .

If I interpret correctly, the warning is basically saying that, if you want to begin a painter on a widget, you should do it in THE same widget's paint event.

In Qt 4.8 documentation

QPainter::QPainter(QPaintDevice * device)

Constructs a painter that begins painting the paint device immediately.

this means by calling the QPainter constructor with a target device, it begin s immediately.

So, try hijacking the scroll area's paint event.

FYI, whenever you hijack a event in Qt, I recommend calling the base class's implementation first in you new implementation like this so the base class's behavior is preserved.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM