Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Message Box X Button Works like the Cancel Button Of the Box
Forum Updated to NodeBB v4.3 + New Features

Message Box X Button Works like the Cancel Button Of the Box

Scheduled Pinned Locked Moved Solved General and Desktop
13 Posts 3 Posters 4.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Abhi_Varma
    wrote on last edited by
    #1

    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.

    1.JPG

    Here on clicking that push button. It will show a MessageBox.

    2.JPG

    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.

    3.JPG

    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

    1. why is this happening? Internally are they same or calling same method?
    2. How can I get the code in the else block get executed when clicked on X button?
    B 1 Reply Last reply
    0
    • A Abhi_Varma

      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.

      1.JPG

      Here on clicking that push button. It will show a MessageBox.

      2.JPG

      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.

      3.JPG

      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

      1. why is this happening? Internally are they same or calling same method?
      2. How can I get the code in the else block get executed when clicked on X button?
      B Offline
      B Offline
      Bonnie
      wrote on last edited by Bonnie
      #5

      @Abhi_Varma

      1. 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.
      2. 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 like

      QMessageBox 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";
      }
      
      A 1 Reply Last reply
      2
      • Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #2

        What should happen else? The dialog was discarded by clicking on the 'X'. I don't see why another (spurious) return value should be returned in this case.

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        A 1 Reply Last reply
        0
        • Christian EhrlicherC Christian Ehrlicher

          What should happen else? The dialog was discarded by clicking on the 'X'. I don't see why another (spurious) return value should be returned in this case.

          A Offline
          A Offline
          Abhi_Varma
          wrote on last edited by Abhi_Varma
          #3

          @Christian-Ehrlicher Then the having the "Discard Changes" button is of no use when it does the same thing. What I want is on clicking the "X" button I need it to run the else part. Is there a way?

          The scenario I'm thinking. I have a properties page of a device, the user after filling it when the user clicks "OK". This Message Box should appear. On clicking "Save Changes" internally a saveProperties() will be triggered, It will do its thing and it will also close the properties dialog. Similarly, On clicking the "Discard Changes" Button it will call discardChanges() is triggered it does its thing and closes the properties dialog, but on clicking the "X" button only the Message Box should be closed and the properties dialog should be remained opened so that the user can continue editing the device properties.

          But from the simple example, I gave. if it's implemented for the above scenario then on clicking the "X" button it will call the discardChanges() and close the properties dialog.

          1 Reply Last reply
          0
          • Christian EhrlicherC Offline
            Christian EhrlicherC Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #4

            Then I would expect a third button for this.

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            A 1 Reply Last reply
            0
            • A Abhi_Varma

              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.

              1.JPG

              Here on clicking that push button. It will show a MessageBox.

              2.JPG

              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.

              3.JPG

              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

              1. why is this happening? Internally are they same or calling same method?
              2. How can I get the code in the else block get executed when clicked on X button?
              B Offline
              B Offline
              Bonnie
              wrote on last edited by Bonnie
              #5

              @Abhi_Varma

              1. 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.
              2. 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 like

              QMessageBox 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";
              }
              
              A 1 Reply Last reply
              2
              • Christian EhrlicherC Christian Ehrlicher

                Then I would expect a third button for this.

                A Offline
                A Offline
                Abhi_Varma
                wrote on last edited by
                #6
                This post is deleted!
                1 Reply Last reply
                0
                • B Bonnie

                  @Abhi_Varma

                  1. 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.
                  2. 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 like

                  QMessageBox 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";
                  }
                  
                  A Offline
                  A Offline
                  Abhi_Varma
                  wrote on last edited by
                  #7

                  @Bonnie Okay this looks interesting.... so can I hide the cancel button from the user while making X button stay active

                  B 1 Reply Last reply
                  0
                  • A Abhi_Varma

                    @Bonnie Okay this looks interesting.... so can I hide the cancel button from the user while making X button stay active

                    B Offline
                    B Offline
                    Bonnie
                    wrote on last edited by Bonnie
                    #8

                    @Abhi_Varma
                    Wow, I would never think of that, but yes you can...
                    I've tried

                    box.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. :)

                    A 1 Reply Last reply
                    0
                    • B Bonnie

                      @Abhi_Varma
                      Wow, I would never think of that, but yes you can...
                      I've tried

                      box.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. :)

                      A Offline
                      A Offline
                      Abhi_Varma
                      wrote on last edited by Abhi_Varma
                      #9

                      @Bonnie thanks for the quick response.... by the way is it a gud practice to do it this way?

                      B 1 Reply Last reply
                      0
                      • A Abhi_Varma

                        @Bonnie thanks for the quick response.... by the way is it a gud practice to do it this way?

                        B Offline
                        B Offline
                        Bonnie
                        wrote on last edited by
                        #10

                        @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.

                        A 2 Replies Last reply
                        0
                        • B Bonnie

                          @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.

                          A Offline
                          A Offline
                          Abhi_Varma
                          wrote on last edited by
                          #11

                          @Bonnie thank you so much :)

                          1 Reply Last reply
                          0
                          • B Bonnie

                            @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.

                            A Offline
                            A Offline
                            Abhi_Varma
                            wrote on last edited by
                            #12

                            @Bonnie is there any other way to implement this?

                            B 1 Reply Last reply
                            0
                            • A Abhi_Varma

                              @Bonnie is there any other way to implement this?

                              B Offline
                              B Offline
                              Bonnie
                              wrote on last edited by Bonnie
                              #13

                              @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.

                              1 Reply Last reply
                              0

                              • Login

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved