Results 1 to 5 of 5

Thread: Reopen Form Widget after deletion

  1. #1
    Join Date
    Aug 2016
    Posts
    5
    Thanks
    4
    Qt products
    Qt5
    Platforms
    Windows

    Default Reopen Form Widget after deletion

    I want to open a new form, close it an reopen it.

    However, when I reopen it, all changed stuff still is there (like text in a label or something like that). Now I am not really concerned with these trivial visual ... leftovers, but more with the inner working. Will a timer keep running after i close this window? Keep updating labels with pictures? (I don't really want that by default)

    So what I want is : I open a new form, after that form is closed, it will be destroyed an renewed. This would result in a fresh screen ready to start.

    I know it is not that crazy. In VB.NET it looks like this:

    // the initialization :
    Qt Code:
    1. Private WithEvents _frmLogging As frmLogging
    To copy to clipboard, switch view to plain text mode 
    //opening the form, by pressing a button or something
    Qt Code:
    1. _frmLogging = New frmLogging
    2. _frmLogging.Show()
    To copy to clipboard, switch view to plain text mode 
    //deleting it when it is closed :
    Qt Code:
    1. Private Sub CatchClosingLog(sender As Object, e As EventArgs) Handles _frmLogging.FormClosed
    2. _frmLogging.Dispose()
    3. _frmLogging = Nothing
    4. End Sub
    To copy to clipboard, switch view to plain text mode 
    I want to replicate this in Qt . frmMain is my Qmainwindow and I want to open frmTest which is represented by oTestFrame.
    Qt Code:
    1. void frmMain::on_btnOpenNew_clicked()
    2. {
    3. oTestFrame.show();
    4. __hook(&frmTest::FormClosed, &oTestFrame, &frmMain::OnCloseSecondTry); //Here I create an event. This allows me to run code in [I]frmMain[/I] after [I]frmTest[/I] is closed
    5. }
    To copy to clipboard, switch view to plain text mode 
    When oTestFrame is closed, OnCloseSecondTry is executed. That is were it all goes wrong.
    Qt Code:
    1. void frmMain::OnCloseSecondTry()
    2. {
    3. __unhook(&frmTest::FormClosed,& oTestFrame, &frmMain::OnCloseSecondTry); //unhook event, just good practice, I don't really think it will matter after the object is destroyed (Am I wrong?)
    4. oTestFrame.~frmTest();
    5. frmTest oTemp;
    6. oTestFrame = &oTemp;
    7. }
    To copy to clipboard, switch view to plain text mode 
    The important variables are declared in frmMain.h :
    Qt Code:
    1. ...
    2. private:
    3. frmTest oTestFrame;
    4. void OnCloseSecondTry();
    5. ...
    To copy to clipboard, switch view to plain text mode 
    I destroy oTestFrame. But I can not insert a fresh frmTest object in oTestFrame.
    I read somewhere you could not store a Qwidget in a Qwidget. Is that true?
    How can i get this to work? Any suggestions welcome :P

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Reopen Form Widget after deletion

    You can just set the Qt::WA_DeleteOnClose widget attribute, then it will be deleted when it is closed.

    Cheers,
    _

  3. The following user says thank you to anda_skoa for this useful post:

    Fivezero05 (12th August 2016)

  4. #3
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Reopen Form Widget after deletion

    I read somewhere you could not store a Qwidget in a Qwidget. Is that true?
    Don't believe everything you read, especially if you read it "somewhere"...

    The whole architecture of building complex GUIs in Qt is based on storing QWidget pointers as members (and children) of other QWidgets. However, these are pointers. QWidgets are not copyable or assignable; that is, you cannot write code like:

    Qt Code:
    1.  
    2. a = b;
    3.  
    4. QWidget c = a;
    5.  
    6. // etc.
    To copy to clipboard, switch view to plain text mode 

    You can write code that manipulates QWidget pointers or references:

    Qt Code:
    1. QWidget * a = new QWidget();
    2. QWidget * b = new QWidget();
    3.  
    4. a = b; // a and b both point to the same QWidget instance; the previous b instance is lost and is a memory leak...
    5.  
    6. QWidget * c = a; // c now points to the same QWidget instance as a and b
    To copy to clipboard, switch view to plain text mode 

    You can do this, but it isn't generally recommended in most cases:

    Qt Code:
    1. class MyWidget : public QWidget
    2. {
    3. Q_OBJECT;
    4.  
    5. // ...
    6.  
    7. private:
    8. SomeOtherWidget a;
    9. };
    To copy to clipboard, switch view to plain text mode 

    The main reason why this isn't recommended is that having widgets (not widget pointers) as members of other widgets can interfere with the parent-child ownership relationships inherent in Qt. If you initialize "a" with a pointer to "this" (i.e. the MyWidget instance being constructed), then when the MyWidget instance goes out of scope, you could end up in a double destruction situation - "a" gets destroyed because it is a member variable of MyWidget, but the MyWidget instance also tries to destroy it because it is its child. One of those will lose. The only way to do it successfully is to construct "a" with no parent.

    When I would use something like this is if "SomeOtherWidget" is a QDialog or other complex widget that is expensive to construct or if I want its contents to persist from invocation to invocation. Then I can just re-use the instance each time I need to post the dialog, and it will retain all of the settings that it had when it was last invoked. If I want a fresh dialog with a default initialization each time, then I don't use this method, I create the dialog as a stack variable in the function that invokes it.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. The following user says thank you to d_stranz for this useful post:

    Fivezero05 (12th August 2016)

  6. #4
    Join Date
    Aug 2016
    Posts
    5
    Thanks
    4
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Reopen Form Widget after deletion

    Thanks to d_stranz and anda_skoa, I was able to solve my problem :P Here is how i did it.

    frmMain represents the Qmainwindow.
    frmTest is the extra window I want to open and close. The variable for this is oTestFrame.

    frmMain.h
    Qt Code:
    1. ...
    2. private:
    3. frmTest * oTestFrame ; //how frmTest should be defined. This is a pointer.
    4. private slots:
    5. void onClosed();
    6. ...
    To copy to clipboard, switch view to plain text mode 
    frmMain.cpp
    Qt Code:
    1. frmMain::frmMain(QWidget *parent)
    2. : QMainWindow(parent)
    3. {
    4. ui.setupUi(this);
    5.  
    6. oTestFrame = new frmTest(); //for the first time, we initialize the object in the frmMain constructor. Now we can check if a form already exists or not
    7. }
    8.  
    9. void frmMain::on_btnOpenNew_clicked() //this can be anything. For this case, a button was used.
    10. {
    11. if (!oTestFrame->isActiveWindow()) //only one window can exist at all time.
    12. {
    13. oTestFrame->show();
    14. QObject::connect(oTestFrame, SIGNAL(destroyed()), this, SLOT(onClosed()));
    15. }
    16. }
    17.  
    18. void frmMain::onClosed()
    19. {
    20. QObject::disconnect(oTestFrame, SIGNAL(destroyed()), this, SLOT(onClosed())); //I don't really know for sure if this is necessary, after destruction, but hey, you never know
    21. oTestFrame = new frmTest(); //ready a new form te be opened. All previous changes are lost, which was the point.
    22.  
    23. }
    To copy to clipboard, switch view to plain text mode 

    frmTest.cpp : not a lot extra code is needed to let this work
    Qt Code:
    1. frmTest::frmTest(QWidget *parent)
    2. : QWidget(parent)
    3. {
    4. ui.setupUi(this);
    5. this->setAttribute(Qt::WA_DeleteOnClose, true); // This makes sure the form is destroyed after it is closed.
    6. }
    To copy to clipboard, switch view to plain text mode 

  7. #5
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Reopen Form Widget after deletion

    I would change that to connect() right after creating the object.

    And there is no need to disconnect, the object is gone afterwards.

    Neither of which is even necessary if you use a QPointer to track the object and only create one when you need it.

    Qt Code:
    1. private:
    2. QPointer<frmTest> oTestFrame;
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. void frmMain::on_btnOpenNew_clicked()
    2. {
    3. if (!oTestFrame) {
    4. oTestFrame = new frmTest();
    5. oTestFrame->show();
    6. }
    7. }
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

Similar Threads

  1. Reopen the MainWindow
    By thibs in forum Qt Programming
    Replies: 14
    Last Post: 14th February 2017, 01:58
  2. Replies: 0
    Last Post: 27th July 2016, 22:05
  3. how can i access other form widget
    By crissti_cta in forum Newbie
    Replies: 2
    Last Post: 14th December 2010, 21:51
  4. Replies: 5
    Last Post: 12th March 2010, 22:43
  5. Open one Form (widget)
    By vinny gracindo in forum Newbie
    Replies: 1
    Last Post: 7th October 2009, 14:13

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.