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_sendSpontan开发者_运维知识库eousEvent 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.
精彩评论