Understanding the different ways to instantiate the QMessageBox class



  • Hi,

    I have used QMessageBox a few times without understanding it completely. Can someone help me to understand the two different ways it can be used? I know this may be a C++ question but since it's related to a Qt class you guys may have a better explanation than just posting it in a C++ forum.

    I have been using what I think is a static function of the QMessageBox which has been doing what I needed, but today when I tried to use the informativeText class I realized that I didn't fully understand how the QMessageBox class works (this may apply to some other classes not just the QMessageBox).

    This is how I have been using the static function
    @QMessageBox::information(this,"title", "Message");@

    And this is the way I used the class when using the informativeText function and here is where I have the question.
    @QMessageBox msg;
    msg.setText("Messsage");
    msg.setInformativeText("Some more detail information");
    msg.exec();@

    Why is that the "new" keyword is not used when instantiating the QMessageBox? In other words I was expecting to do something like...

    @QMessageBox *msg = new QMessageBox();
    msg->setText... etc@

    ...basically using the new keyword and creating a pointer.

    The other question is why do I need the exec() function in order to execute the instance of the QMessageBox class?

    I did read the documentation but I don't understand how this is working. Again I'm just trying to understand how things are working.

    As allways thanks a lot for your help.



  • Some info on your second question:

    Sometimes you want to prepare a message box, but not use it yet. For example, the message box might be populated with information that is available at different times in your program flow; until the information is complete, you want to keep the box hidden.

    Then when you want to use it, you call exec() or show().

    exec() and show() are different. Show does the obvious thing of making the message box appear. Exec makes the box more like a function call: i.e. the box appears and after the user completes the dialog, the resulting information is returned into a variable and the box closes. For example, I might use show() with a non-modal dialog, and exec() with a modal dialog.

    HTH,
    Owen



  • Make sense, thanks a lot , now I just need to understand what I asked in my first question.

    Thanks a lot


  • Moderators

    [quote author="fs_tigre" date="1342405672"]
    This is how I have been using the static function
    @QMessageBox::information(this,"title", "Message");@

    And this is the way I used the class when using the informativeText function and here is where I have the question.
    @QMessageBox msg;
    msg.setText("Messsage");
    msg.setInformativeText("Some more detail information");
    msg.exec();@

    Why is that the "new" keyword is not used when instantiating the QMessageBox? In other words I was expecting to do something like...

    @QMessageBox *msg = new QMessageBox();
    msg->setText... etc@

    ...basically using the new keyword and creating a pointer, but it doesn't work.
    [/quote]

    As you have recognized already there are different ways to use QMessageBox. The static method is for displaying a message box quickly. IMHO it is more a matter of taste and preference which you are using.

    However, the non-static methods you are referring are different from the location where you are placing the instance. The first method uses the stack for the complete object. The second method is using the heap. "See this for a short information on heap and stack.":http://www.quora.com/C-programming-language/What-is-the-stack-and-heap-memory-architecture-used-by-C
    The second method places only the pointer to the object on the stack.

    With the first method the object will be destructed when you are leaving the focus where the instantiation happened (E.g. leaving the routine).

    The second method uses a pointer and you need to point it to memory. The "new" is doing the allocation of memory. One important part you left out in your example is the destruction of the memory with "delete" later on. That is important because if you forget you will have a memory leak. If you are doing this in a routine regularly called you will run out of memory after some time.

    I am wondering, why this should not. You need to give more details on this.



  • When using exec() on a QDialog (-derived) class, you start a local eventloop in the dialog. QMessageBox is a QDialog derived class. That means that your call to exec() will not return untill the dialog is dismissed. It results in a modal dialog that blocks the rest of your application. Usually, you will use the results of these dialogs immediately in the function where you executed them, and you don't need the dialog to be around anymore outside of the scope of that function. In such cases, it makes sense to create the dialog on the stack instead of on the heap. It is a bit[1] faster, and it prevents memory leaks because no matter what your code path is, the moment the variable goes out of scope (at the latest when you exit the funtion), the dialog will be automatically properly destructed.

    Had you created the dialog on the heap, it would have been your own responsibility to destroy the dialog after you were done with it (or use a smartpointer to do that for you, of course).

    On your second question: you don't. First of all: the static methods use the exec() method, or something close enough anyway. There are other ways to work with a dialog though. There is of course the show() method, which will show your dialog but otherwise continue the normal flow of the function. That is, it returns immediately to the function it was called from. There is also the open() method, which allows you to create an asynchronic modal dialog. These methods are harder to use, but they actually result in more robust code. You will have to deal with the results of your dialog in a different function from the function that triggered the dialog then.

    I'll give you an example of why exec() [2] -could be- is problematic:

    You think that exec() will result in complete synchronous code, and that it will nicely wait for exec() to return. Actually, your application still can respond to stimuli from outside the application. It can respond to network event, to DBUS commands, local sockets and to <deighty> know what other events. Not to mention painting events... What happens if, while you're happily waiting in your exec() call for the user to click that OK button, a command comes in that directly or indirectly destroys the object that created the messagebox? Let me tell you: you trigger a crash. That is not a far-fetched scenario, it was actually discovered as something that was quite "easy to trigger":http://blogs.kde.org/node/3919 in basically any KDE application.

    [1] Not much faster in this case, because the dialog itself will create it's own internal objects like the buttons on the dialog on the heap again, so most of it will end up on the heap no matter what you do.
    [2] And the problems don't stop at exec() either. processEvents() suffers from much the same issues for example.



  • by this way you may customize your messagebox in the mean time before sowing to end-user, what you want to show, like icons, text size, color etc. static means OS default implementation.



  • As expected I learned something new, I had never heard about the heap, in the class I recently took we only talked about the stack but I think it's because we didn't get too much in depth in memory management.

    To add to the use of the "new" keyword.
    http://stackoverflow.com/questions/655065/when-should-i-use-the-new-keyword-in-c

    Quick question, I know I need to have a better understanding about memory management and C++ in general but something comes to my mind, If I understood this correctly when the "new" keyword is used you are allocating memory in the heap which is when you have to manually mange memory and I was wondering if it would be a good idea to instantiate without the use of the "new" keyword basically allocating memory to the stack which could prevent memory leaks.

    Is it possible to write a complete program without using the "new" keyword in Qt or C++ in general? If yes, what would be the biggest issue or limitation by doing it this way?

    Thanks a lot for your help.


  • Moderators

    [quote author="fs_tigre" date="1342443895"]
    Quick question, I know I need to have a better understanding about memory management and C++ in general but something comes to my mind, If I understood this correctly when the "new" keyword is used you are allocating memory in the heap which is when you have to manually mange memory and I was wondering if it would be a good idea to instantiate without the use of the "new" keyword basically allocating memory to the stack which could prevent memory leaks.

    Is it possible to write a complete program without using the "new" keyword in Qt or C++ in general? If yes, what would be the biggest issue or limitation by doing it this way?
    [/quote]

    It all depends on the size of your stack. In previous time it was more of an issue than today.

    However, it is not a good a advice to allocate all objects on the stack. Typically larger objects are being allocated with new in order to avoid the memory limitations associated with the stack.

    Pointers and memory allocation have the issue of possible memory leaks. But as already brought up by Andre above there are mechanisms to avoid the leakage (E.g. "QScopedPointer).":http://qt-project.org/doc/qt-4.8/qscopedpointer.html#details

    In addition there are situation where there is no way around pointers and the memory allocation.



  • Possible? Yes. Probable beyond the non-trivial case? No. No heap, not even behind the scenes? No way.

    One limit you'll run into is that stack size is limited. Much more limited than heap size. Another limitation when using the Qt is that most Qt object (all QObjects and everything derived from that) are not copyable. Another thing is that you'll run into issues with constructing your GUI. It's going to be very hard to do using stack only.

    Lucky for you, Qt has freed you from a part of the memory management issues linked to using the heap. QObjects can be created with a parent QObject, and a parent will make sure all children are destroyed when the parent is destroyed. That way, you only need to keep track of the top-level items you create. The rest Qt will manage for you.



  • Thank you all very much for the good information, this is really helping me a lot.


Log in to reply
 

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