QImage::load导致应用程序崩溃

3

我不知道为什么,但这段代码会导致我的应用程序崩溃。当我在setPicture方法中使用一个全新的指向QImage的指针时,它就不会崩溃!是什么原因导致了这种行为?

Canvas类:

#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);
}

以下是Window类:

#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();

    }
}

这里是调用堆栈追踪:

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 

两者之间没有区别。问题出在其他地方。同时,在类的作用域内访问其成员时不需要使用“this”。 - Mahesh
代码看起来没问题。你在调试器中运行了代码吗?你有什么错误信息? - laurent
另外,在 Canva 的构造函数中,您应该将内部指针 p 初始化为 NULL。未初始化的指针会带来很多问题,因此这并不是一个好主意。 - laurent
预览未初始化? - TheHorse
糟糕!我发现了问题。你能看出来吗? - user336063
显示剩余3条评论
1个回答

1

在Window类的构造函数中声明和实例化Canvas类的指针,而不是使用私有声明的指针。

如果我没记错的话,在调用browseFile方法时,窗口构造函数中的Canvas指针已经超出了作用域。

应该是:

class Window : public QWidget
{
    Q_OBJECT

    private:
        Canvas *preview;

    public:
        Window();

    public slots:
        void browseFile();
};

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

虽然我不知道setPicture是如何被调用的!

教训:不要在构造函数中声明任何你计划后来使用的东西。


不错,这个问题也曾经困扰过我。希望编译器能够给出一些警告或提示。 - laurent

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接