Message Box X Button Works like the Cancel Button Of the Box
-
Then I would expect a third button for this.
-
I am facing some difficulty understanding how the functionality of the QMessage box is working. Here I have created a Simple Dialog box with a push button.
Here on clicking that push button. It will show a MessageBox.
Below I have attached the code for the QMessageBox.
void dialog::on_pushButton_clicked() { QMessageBox box; box.setText("Choose An Option"); QPushButton *pDiscardChangesBtn = box.addButton("Discard Changes", QMessageBox::RejectRole); QPushButton *pSaveChangesBtn = box.addButton("Save Changes", QMessageBox::AcceptRole); box.setDefaultButton(pSaveChangesBtn); box.exec(); if(box.clickedButton() == pSaveChangesBtn) { qInfo() << "Save Changes Button Clicked"; } else if(box.clickedButton() == pDiscardChangesBtn) { qInfo() << "Discard Changes Button clicked"; } else { qInfo() << "Closed"; } }
here I have attached the output of the terminal.
I got the above output by first selecting "Save Changes" btn, then "Discard Changes" btn, the X button of the MessageBox Window.
Here I have noticed that on clicking "Discard Changes" btn, X button of the windows same block of code (else if block) is getting executed.
My doubt is
- why is this happening? Internally are they same or calling same method?
- How can I get the code in the else block get executed when clicked on X button?
- Internally QMessageBox will try to find an "escape" button from all buttons to set as the clicked button when "Escape" key is pressed or X is clicked,
QMessageBox::RejectRole
is one of the case to be chosen. - If there is no such button, the X will be disabled.
So if you don't want the discard button and X to act the same, just don't set it's role to
QMessageBox::RejectRole
.
QMessageBox::DestructiveRole
is more suitable for that case.You can also use
StandardButtons
likeQMessageBox box; box.setText("Choose An Option"); box.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); //I add cancel to make X enabled box.setDefaultButton(QMessageBox::Save); int result = box.exec(); if(result == QMessageBox::Save) { qInfo() << "Save Button Clicked"; } else if(result == QMessageBox::Discard) { qInfo() << "Discard Button clicked"; } else { qInfo() << "Cancelled"; }
-
Then I would expect a third button for this.
This post is deleted! -
- Internally QMessageBox will try to find an "escape" button from all buttons to set as the clicked button when "Escape" key is pressed or X is clicked,
QMessageBox::RejectRole
is one of the case to be chosen. - If there is no such button, the X will be disabled.
So if you don't want the discard button and X to act the same, just don't set it's role to
QMessageBox::RejectRole
.
QMessageBox::DestructiveRole
is more suitable for that case.You can also use
StandardButtons
likeQMessageBox box; box.setText("Choose An Option"); box.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); //I add cancel to make X enabled box.setDefaultButton(QMessageBox::Save); int result = box.exec(); if(result == QMessageBox::Save) { qInfo() << "Save Button Clicked"; } else if(result == QMessageBox::Discard) { qInfo() << "Discard Button clicked"; } else { qInfo() << "Cancelled"; }
@Bonnie Okay this looks interesting.... so can I hide the cancel button from the user while making X button stay active
- Internally QMessageBox will try to find an "escape" button from all buttons to set as the clicked button when "Escape" key is pressed or X is clicked,
-
@Bonnie Okay this looks interesting.... so can I hide the cancel button from the user while making X button stay active
@Abhi_Varma
Wow, I would never think of that, but yes you can...
I've triedbox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); box.button(QMessageBox::Cancel)->hide();
or in your orignal code
QPushButton *pDiscardChangesBtn = box.addButton("Discard Changes", QMessageBox::DestructiveRole); QPushButton *pSaveChangesBtn = box.addButton("Save Changes", QMessageBox::AcceptRole); QPushButton *pCancelBtn = box.addButton(QMessageBox::Cancel); pCancelBtn->hide();
It can do the trick. :)
-
@Abhi_Varma
Wow, I would never think of that, but yes you can...
I've triedbox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); box.button(QMessageBox::Cancel)->hide();
or in your orignal code
QPushButton *pDiscardChangesBtn = box.addButton("Discard Changes", QMessageBox::DestructiveRole); QPushButton *pSaveChangesBtn = box.addButton("Save Changes", QMessageBox::AcceptRole); QPushButton *pCancelBtn = box.addButton(QMessageBox::Cancel); pCancelBtn->hide();
It can do the trick. :)
@Bonnie thanks for the quick response.... by the way is it a gud practice to do it this way?
-
@Bonnie thanks for the quick response.... by the way is it a gud practice to do it this way?
@Abhi_Varma
Well, it is not a normal way since Qt intentionally disable X button when there's no escape button.
So this is kind of a cheat way.
Also there's no guarantee that it will always work as expected in all future Qt versions.
I would keep the cancel button if I don't have to hide it. -
@Abhi_Varma
Well, it is not a normal way since Qt intentionally disable X button when there's no escape button.
So this is kind of a cheat way.
Also there's no guarantee that it will always work as expected in all future Qt versions.
I would keep the cancel button if I don't have to hide it.@Bonnie thank you so much :)
-
@Abhi_Varma
Well, it is not a normal way since Qt intentionally disable X button when there's no escape button.
So this is kind of a cheat way.
Also there's no guarantee that it will always work as expected in all future Qt versions.
I would keep the cancel button if I don't have to hide it.@Bonnie is there any other way to implement this?
-
@Bonnie is there any other way to implement this?
@Abhi_Varma
What do you mean? To have the X button enabled without adding and hiding a cancel/close button?
You can, for example, write your own dialog instead of using QMessageBox and handle everything by yourself, but I think there's no need to do that.
I would say hiding the button is already the best solution in my opinion...
If you really need the button invisible, just do it.
I would also cheat / try to change Qt's behavior in my code if I have to.