[SOLVED] How to destroy widget when close QDockWidget



  • Hi All!
    I Have QMainWindow, at this main window, i add QDockWidget, to this dock widget, i add some widget, when i close dockWidget (push "X" at user interface), widget don't call destructor, why? I think DockWidget not destroyed when user click to close button but set visibility false to this DockWidget. I'm right? And if i won't to clear memory, i need connect to @void visibilityChanged ( bool visible )@ signal, and hear call delete for widget, or may be has some other way?

    my code:
    @QMainWindow * m = new QMainWindow();
    QDockWidget *inf = new QDockWidget(tr("Information"), m);
    inf->setAllowedAreas(Qt::AllDockWidgetAreas);
    inf->setWidget(new InformationDialog(m));
    m->addDockWidget(Qt::BottomDockWidgetArea, inf);
    @



  • @inf->setWidget(new InformationDialog(m));@

    The parent of your InformationDialog is m(QMainWindow). set inf as parent of InformationDialog and try.

    Something like this
    @inf->setWidget(new InformationDialog(inf));@



  • I don't think you need to pass any parent there at all, it will be reparented when you call setWidget anyway.
    To make a widget delete itself when it's closed, use the Qt::WA_DeleteOnClose widget attribute.



  • When i set @inf->setWidget(new InformationDialog(inf));@ window show like dialog in main window;
    Set attribute Qt::WA_DeleteOnClose at InformationDialog - nothing happen :(



  • bq. When i set @inf->setWidget(new InformationDialog(inf));@ window show like dialog in main window;

    Not sure I underastand what you mean by this. Does it make a difference what you pass as parent?

    bq. Set attribute Qt::WA_DeleteOnClose at InformationDialog – nothing happen :(

    But you want to set it on the dock widget, inf. That's the one that can be closed by the user.



  • I have tried it on my Qt Creator. DockWidget is not deleted when we close it. Dock widget is deleted only when we close the application. So, your InformationDialog is deleted when you close the application ( InformationDialog widget becomes child of your DockWidget when you call setWidget() ).

    So the question is do you want to delete QDockWidget when you close it , or you want to delete only InformationDialog??

    Sorry for my earlier post, I have never used QMainWindow or QDockWidget. I program for Symbain.



  • yes, i need delete InformationDialog, when i close DockWidget, at best case - delete DockWidget too.



  • Then you can do one think.. call a slot when visibilityChanged signal of QDocWidget is called and inside that you can delete QDocWidget if visibility == false;

    this is how my sample implementation is ..
    DockWidget.h
    @#ifndef DOCKWIDGET_H
    #define DOCKWIDGET_H
    #include <QDockWidget>
    class DockClass : public QDockWidget
    {
    Q_OBJECT
    public:
    DockClass(QWidget * parent = 0):QDockWidget(parent)
    {
    }
    public slots:
    void visibilityChanged1(bool visiblity);

    public:
    ~DockClass() {
    int a = 0;
    a++; // just to see that this destructor is called.
    }
    };
    #endif // DOCKWIDGET_H@

    my main.cpp
    @#include <QPushButton>
    #include <QMainWindow>
    #include <QtGui/QApplication>
    #include <QDockWidget>
    #include "DockWidget.h"

    void DockClass::visibilityChanged1(bool visiblity) {
    if(!visiblity)
    deleteLater(); // this will delete DocClass which intern will delete buttonClass also.
    }
    int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);

    QMainWindow mainWindow;
    DockClass * dockWidget = new DockClass();
    QObject::connect(dockWidget,SIGNAL(visibilityChanged(bool)),dockWidget,SLOT(visibilityChanged1(bool)));
    
    mainWindow.setCentralWidget(dockWidget);
    QPushButton * buttonClass = new QPushButton(dockWidget);
    buttonClass->setAttribute(Qt::WA_DeleteOnClose);
    dockWidget->setWidget(buttonClass);
    mainWindow.show();
    
    return app.exec&#40;&#41;;
    

    }@



  • tnx, but I hope Qt has some easy way to do that or I'm make a mistake?



  • Tnx all for help, I do that:
    @void SomeClass::onInformation(){
    QObject * m = parent();
    while(m != NULL){
    QString str = m->metaObject()->className();
    if(str == "QMainWindow"){
    break;
    }
    m = m->parent();
    }
    if(m == NULL)
    return;
    QDockWidget *inf = new QDockWidget(tr("Information"), m);
    inf->setWidget(new InformationWidget(inf));
    m->addDockWidget(Qt::BottomDockWidgetArea, inf);
    connect(inf, SIGNAL(visibilityChanged(bool)), this, SLOT(onVisibilityChangedInformaionWidget(bool)));
    }
    //--------------------------------------------------------------------------------------------------
    void SomeClass::onVisibilityChangedInformaionWidget( bool visibility ){
    QObject * m = parent();
    while(m != NULL){
    QString str = m->metaObject()->className();
    if(str == "QMainWindow"){
    break;
    }
    m = m->parent();
    }
    if(m == NULL)
    return;

    QDockWidget * dock = qobject_cast<QDockWidget *> (sender());
    if(dock == NULL)
    return;
    m->removeDockWidget(dock);
    dock->deleteLater();
    }@



  • So what was wrong with just doing inf->setAttribute(Qt::WA_DeleteOnClose)?
    Works just fine for me, and seems a whole lot easier...



  • [quote author="ludde" date="1310389011"]So what was wrong with just doing inf->setAttribute(Qt::WA_DeleteOnClose)?
    Works just fine for me, and seems a whole lot easier...[/quote]

    I want to try this and see if this works. I will updated this post if it works.



  • I try to do @setAttribute(Qt::WA_DeleteOnClose);@ for widget that isn't work, but @inf->setAttribute(Qt::WA_DeleteOnClose);@ for DockWidget works! My fall :(. Tnx a lot, it's match easy.



  • @maxim.prishchepa Also I just wanted to add so that other users will get this info as well. It didn't start working until I did QDockWidget.setParent(None). Unparenting it allowed Qt to finally destroy the widget once the parent wasn't holdinging onto it anymore.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.