简体   繁体   中英

QImage::load causes application to crash

I have no idea why but this code causes my application to crash. When I use a brand-new pointer to a QImage in the setPicture method, it doesn't! What could cause this behavior?

Canvas class:

#include <QtGui>

class Canvas : public QWidget
{
    Q_OBJECT

public:
    QImage *p;

    Canvas();
    void setPicture(QString);
};

Canvas::Canvas()
{

}

void Canvas::setPicture(QString filename)
{
    // This causes crash.
    this->p = new QImage;
    this->p->load(filename);

    // This does not cause crash.Why?
    //QImage *z = new QImage;
    //z->load(filename);
}

Here's the Window class:

#include <QtGui>

#include "Canvas.h"

class Window : public QWidget
{
    Q_OBJECT

private:
    Canvas *preview;

public:
    Window();

public slots:
    void browseFile();
};

Window::Window()
{
    QGridLayout *layout = new QGridLayout;
    Canvas *preview = new Canvas;
    preview->setMinimumSize(400,200);
    QSlider *slider = new QSlider;
    slider->setOrientation(Qt::Horizontal);
    QPushButton *browse = new QPushButton("Browse...");

    layout->addWidget(preview, 1, 1);
    //layout->addWidget(slider, 1, 2);
    layout->addWidget(browse, 2, 2);

    this->setLayout(layout);

    this->resize(600,300);

    QObject::connect(browse, SIGNAL(clicked()), SLOT(browseFile()));

}

void Window::browseFile()
{
    QString filename;

    filename = QFileDialog::getOpenFileName(this, "Open Picture", "", "Image Files (*.png *.jpg *.bmp)");

    if(!filename.isEmpty())
    {
        qDebug() << "filename: "+filename;
        preview->setPicture(filename);
        //preview->repaint();

    }
}

Heres the call stack trace...

0 Canvas::setPicture   Canvas.h   25   0x100003410 
1 Window::browseFile   Window.h   52   0x1000038c1 
2 Window::qt_metacall moc_Window.cpp   72   0x1000025c8 
3 QMetaObject::activate   0   0x100c93ac2 
4 QAbstractButton::clicked   0   0x10063f2ed 
5 QAbstractButtonPrivate::emitClicked   0   0x1003bc61e 
6 QAbstractButtonPrivate::click   0   0x1003bd394 
7 QAbstractButton::mouseReleaseEvent   0   0x1003bd556 
8 QWidget::event  0 0x1000d2a52
9 QAbstractButton::event  0 0x1003bc5e6 
10 QPushButton::event  0 0x100448ad2 
11 QApplicationPrivate::notify_helper  0 0x100086e48 
12 QApplication::notify  0 0x1000877a8 
13 QCoreApplication::notifyInternal  0 0x100c805c6 
14 qt_sendSpontaneousEvent 0 0x1000865da 
15 qt_mac_handleMouseEvent  0 0x10004130a 
16 -[QCocoaView mouseUp:]  0 0x100034be6 
17 -[NSWindow sendEvent:]  0 0x7fff8ca74568 
18 -[QCocoaWindow sendEvent:]  0 0x100039795 
19 -[NSApplication sendEvent:]  0 0x7fff8ca0cd4d 
20 -[QNSApplication sendEvent:]  0 0x10003cc1b 
21 -[NSApplication run]  0 0x7fff8c9a325f 
22 QEventDispatcherMac::processEvents  0 0x100044e7b 
23 QEventLoop::exec  0 0x100c7dc55 
24 QCoreApplication::exec  0 0x100c80bff 
25 main main.cpp 12 0x100002cc0 

The pointer to the Canvas class was declared and instantiated in the constructor of the Window class instead of using the privately declared pointer.

If I'm not mistaken, the pointer to the Canvas in the window's constructor went out of scope by the time the browseFile method was called.

Should have been:

class Window : public QWidget
{
    Q_OBJECT

    private:
        Canvas *preview;

    public:
        Window();

    public slots:
        void browseFile();
};

Window::Window()
{
    QGridLayout *layout = new QGridLayout;
    preview = new Canvas;
    ....

Though it's a mystery to me how setPicture got called at all!

Lesson learned: Don't declare anything in the constructor that you plan on using later.

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