The problem here is that I'm sending "this" from inside the class constructor... this is generally bad practice because depending on what the function you're sending "this" to does, the object might not be fully constructed yet and the whole thing can crash...
By the time you get to the part in your constructor where you are building child widgets and adding them to your MainWindow GUI, the class is as constructed as it needs to be. The important part as far as adding child widgets is concerned is that the QMainWindow base class has been constructed, and that's been done as soon as the initialization part of the constructor is finished (i.e. the : QMainWindow( parent ) bit in the initialization list).
If you think about it, what you want to do is no different from what the setupUI( this ) call is doing in a constructor where the GUI is generated using Qt Designer.
By the way, it is *almost always* an error to create a QWidget instance on the stack and pass it in as "&widget" as you did in your first post in the thread:
Model model;
View view(model, mainWindow);
mainWin->setCentralWidget(&view);
QMainWindow* mainWin = new QMainWindow();
Model model;
View view(model, mainWindow);
mainWin->setCentralWidget(&view);
To copy to clipboard, switch view to plain text mode
In this case, it works because the View instance stays in scope for the duration of main(). However, when you set the parent of a widget (as mainWin->setCentralWidget() does), the parent widget takes ownership of the lifetime of that child and will delete it when it is itself deleted. In your original code, the View instance is created on the stack, which means when you delete the mainWin instance, it will try to delete a stack variable and probably crash your program.
If you are going to do things on the stack in main(), the preferred way is this:
Model model;
View * view = new View( model, 0 ); // assuming your View constructor doesn't default "parent" to 0
mainWin.setCentralWidget( view );
app.exec();
QApplication app;
QMainWindow mainWin;
Model model;
View * view = new View( model, 0 ); // assuming your View constructor doesn't default "parent" to 0
mainWin.setCentralWidget( view );
app.exec();
To copy to clipboard, switch view to plain text mode
This reverses the stack / heap allocation you used. Here, it is perfectly OK to allocate mainWin on the stack, and when it goes out of scope at the end of main(), it will correctly delete the View pointer it holds as a child.
By the way, when you post code, please use [CODE] tags. You can insert them by clicking the "#" icon in advanced editing mode, then type or paste your source code inside them.
Bookmarks