I'm developing a Symbian application. I've written a system for easily changing views, roughly like this:
class ViewManager : public QWidget {
public slots:
void changeView( const QString &id ) {
if( currentView_m ) {
delete currentView_m;
currentView_m = 0;
}
if( id == "main" ) {
currentView = new MainView( this );
}
else if( ... ) {
//etc..
layout_m->addWidget( currentView_m );
connect( currentView_m, SIGNAL( changeView( QString ) ),
this, SLOT( changeView( QString ) ) );
}
private:
View *currentView_m;
};
class View : public QWidget {
signals:
void ChangeView( const QString &id );
};
class MainView : public View {
public slots:
void onButtonClicked() {
emit changeView( "someview" );
}
};
Then as an example, I'm using the ViewManager in main:
int main( int argc, char *argv[] ) {
QApp app...
ViewManager man;
man.changeView( "main" );开发者_开发百科
app.exec();
}
When I change the view the first time, it works just fine, then when I change the view another time, it segfaults! You might think it segfaults when I delete the currentView_m pointer, but no! The segmentation fault happens right after the program exits the changeView-slot.
I have no idea how to debug this, as the program crashes and shows a disassembler dump, and the stack trace shows only gibberish.
Could it be that after the slot call, the program goes to the QApplication event loop and crashes there? I'm using a custom widgets inside View implementations that override some of the protected QWidget events.
You are deleting a object the signal of which you are processing. Instead of delete
, just call deleteLater()
on the object, deferring the deletion to a "safe" point.
Try removing the view from your layout first. Then delete the view. You can use removeWidget,removeItem methods of layout for this purpose
Layout might be trying to access a delete view.
Read this Qt - remove all widgets from layout? question as well. It might give you insight.
精彩评论