Code blocks are created by indenting at least 4 spaces
... and can span multiple lines

class Wizard : public QDialog
{
  Q_OBJECT

  public:
    Wizard(QWidget *parent);

    private slots:
    void what_ever();

    private:
    QPushButton *what_ever;  
};

Wizard::Wizard( QWidget *parent ) : QDialog(parent)
{  
  QGridLayout *layout = new QGridLayout( this );

  QScopedPointer<QTextEdit> textEdit(new QTextEdit); 
  layout->addWidget( textEdit.take(), 0, 0, 1, 2 );

  what_ever = new QPushButton("whatever");
  layout->addWidget(what_ever, 0, 1, 1, 1);

  connect(what_ever, SIGNAL(clicked()), this, SLOT(what_ever()));
}

void Wizard::what_ever()
{
  //blah blah blah
}

I have some problems about the codes.

1 : What if textEdit throw exception?
If "textEdit" throw exception, that means the
destructor of Wizard would not be called,
What would Qt handle the resource of "layout"?

2 : Could I initialize "what_ever" like this?
layout->addWidget(what_ever = new QPushButton("whatever"), 0, 1, 1, 1);
Is this safe in Qt4(4.8)?Would it have any change to cause memory leak?

Thanks a lot

Dani AI

Generated

Brief answers and practical guidance, expanding on points from and .

If an exception is thrown while constructing the Wizard, C++ will unwind and run destructors for fully constructed subobjects (base classes and members). Because QDialog (the base) is already constructed, its destructor will run and QObject's parent/child cleanup will remove/delete children such as a layout or widgets that were parented to the dialog. That means: parent your QObjects (or otherwise guard them) and you will not leak the layout or widgets even if the Wizard constructor fails. If you allocate a heap object without a parent inside the constructor, protect it with RAII (QScopedPointer or a smart pointer) until you attach it to the widget tree.

A few concrete recommendations and gotchas:

  • Prefer immediate parenting: construct widgets with a parent (for example, pass the dialog or container in the widget constructor). That makes ownership explicit and safe on exceptions.
  • If you must create an unparented widget temporarily, use a scope guard (QScopedPointer or similar) and release/take only after the widget is successfully added to the layout.
  • Contrary to a loose description earlier: the layout itself does not "own" widget memory in the same way as a smart pointer. Adding a widget to a layout reparents it to the container widget; the container (the QWidget/QDialog) will delete its children.
  • Avoid throwing exceptions out of slots or across Qt event/slot boundaries; catch them at edges.

Also note a bug in the posted code: the slot and the QPushButton member share the same identifier (what_ever) which is not valid — rename the button or the slot (for example, whatButton and onWhatEverClicked) to avoid compile problems.

Example pattern (clear and exception-friendly):

QTextEdit *text = new QTextEdit(this);   // parented immediately
layout->addWidget(text, 0, 0, 1, 2);

QPushButton *whatButton = new QPushButton("whatever", this);
layout->addWidget(whatButton, 0, 1);
connect(whatButton, &QPushButton::clicked, this, &Wizard::onWhatEverClicked);

Troubleshoot by running the constructor under ASAN/static analysis or temporarily wrapping suspected-throwing code in try/catch to see where exceptions originate.

I've been working extensively with Python and Qt via the PyQt bindings from Riverfront.

First of all, an "object" doesn't throw an exception, code associated with the object does. So what you may want to encapsulate in a try/catch block is any method call on the textEdit. The constructor almost certainly won't throw an exception, so no need to worry about it there.

For your second question, both forms are equivalent, and the layout becomes the owner of the widget. The widget is destroyed when the layout is destroyed, there shoud be no memory-leak as a result. Memory leaks in Qt come about when a widget for some reason needs to keep track of its parent, and then the grandparent releases the parent. Since the parent and child still refer to each other, they can get stranded. So just watch out for unintended cycles in your referencing.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.