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. QListWidget, how to post a question to the user before allowing change?
Forum Updated to NodeBB v4.3 + New Features

QListWidget, how to post a question to the user before allowing change?

Scheduled Pinned Locked Moved Unsolved General and Desktop
25 Posts 7 Posters 4.0k Views 2 Watching
  • 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.
  • VRoninV VRonin

    Example:

    #include <QListWidget>
    #include <QApplication>
    #include <QMessageBox>
    int main(int argc, char *argv[])
    {
       QApplication app(argc,argv);
       QListWidget mainWid;
       mainWid.setSelectionMode(QAbstractItemView::ExtendedSelection);
       for(int i=0;i<5;++i)
           mainWid.addItem(QStringLiteral("Item ") + QString::number(i));
       bool userSelected = true;
       QObject::connect(mainWid.selectionModel(),&QItemSelectionModel::selectionChanged,[&mainWid,&userSelected](const QItemSelection &selected, const QItemSelection &deselected){
           if(!userSelected)
               return;
           if(QMessageBox::question(&mainWid,QStringLiteral("Are you sure?"),QStringLiteral("Are you sure you want to change the selection?")) != QMessageBox::StandardButton::Yes){
               userSelected=false;
               mainWid.selectionModel()->select(selected,QItemSelectionModel::Deselect);
               mainWid.selectionModel()->select(deselected,QItemSelectionModel::Select);
               userSelected=true;
           }
       });
       mainWid.show();
       return app.exec();
    }
    
    SPlattenS Offline
    SPlattenS Offline
    SPlatten
    wrote on last edited by
    #10

    @VRonin , the only problem I've found so far is the order in which the signals are emitted, the list widget signals are emitted before the model selectionChanged signal.

    Kind Regards,
    Sy

    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by
      #11

      Ok, the problem can be solved with a simple reimplementation of the selection model:

      #include <QItemSelectionModel>
      class AskSelectionModel : public QItemSelectionModel{
          Q_OBJECT
          Q_DISABLE_COPY_MOVE(AskSelectionModel)
      public:
          using QItemSelectionModel::QItemSelectionModel;
      public slots:
          void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) override{
              askSelect(selection,command);
          }
          virtual void actuallySelect(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command){
              QItemSelectionModel::select(selection,command);
          }
      signals:
          void askSelect(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command);
      };
      
      int main(int argc, char *argv[])
      {
         QApplication app(argc,argv);
         QListWidget mainWid;
         AskSelectionModel* askModel = new AskSelectionModel(mainWid.model(),&mainWid);
         mainWid.setSelectionMode(QAbstractItemView::ExtendedSelection);
         mainWid.setSelectionModel(askModel);
         for(int i=0;i<5;++i)
             mainWid.addItem(QStringLiteral("Item ") + QString::number(i));
         QObject::connect(askModel,&AskSelectionModel::askSelect,[&mainWid,askModel](const QItemSelection &selection, QItemSelectionModel::SelectionFlags command){
             if(QMessageBox::question(&mainWid,QStringLiteral("Are you sure?"),QStringLiteral("Are you sure you want to change the selection?")) == QMessageBox::StandardButton::Yes){
                 askModel->actuallySelect(selection, command);
             }
         });
         mainWid.show();
         return app.exec();
      }
      

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      SPlattenS 2 Replies Last reply
      3
      • SPlattenS Offline
        SPlattenS Offline
        SPlatten
        wrote on last edited by
        #12

        Thank you, I've now re-designed my GUI interface and now its much simpler and doesn't require any manipulation of the model.

        Kind Regards,
        Sy

        1 Reply Last reply
        0
        • VRoninV VRonin

          Ok, the problem can be solved with a simple reimplementation of the selection model:

          #include <QItemSelectionModel>
          class AskSelectionModel : public QItemSelectionModel{
              Q_OBJECT
              Q_DISABLE_COPY_MOVE(AskSelectionModel)
          public:
              using QItemSelectionModel::QItemSelectionModel;
          public slots:
              void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) override{
                  askSelect(selection,command);
              }
              virtual void actuallySelect(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command){
                  QItemSelectionModel::select(selection,command);
              }
          signals:
              void askSelect(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command);
          };
          
          int main(int argc, char *argv[])
          {
             QApplication app(argc,argv);
             QListWidget mainWid;
             AskSelectionModel* askModel = new AskSelectionModel(mainWid.model(),&mainWid);
             mainWid.setSelectionMode(QAbstractItemView::ExtendedSelection);
             mainWid.setSelectionModel(askModel);
             for(int i=0;i<5;++i)
                 mainWid.addItem(QStringLiteral("Item ") + QString::number(i));
             QObject::connect(askModel,&AskSelectionModel::askSelect,[&mainWid,askModel](const QItemSelection &selection, QItemSelectionModel::SelectionFlags command){
                 if(QMessageBox::question(&mainWid,QStringLiteral("Are you sure?"),QStringLiteral("Are you sure you want to change the selection?")) == QMessageBox::StandardButton::Yes){
                     askModel->actuallySelect(selection, command);
                 }
             });
             mainWid.show();
             return app.exec();
          }
          
          SPlattenS Offline
          SPlattenS Offline
          SPlatten
          wrote on last edited by
          #13

          @VRonin said in QListWidget, how to post a question to the user before allowing change?:

          QItemSelectionModel
          I know this is quite old now, I'm looking at implementing this now, in the slot:

          void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) override{
                  askSelect(selection,command);
              }
          

          Is the line askSelect correct? because its a signal in the class, shouldn't it read:

          emit askSelect(selection, command);
          

          ?

          Kind Regards,
          Sy

          jsulmJ J.HilkJ 2 Replies Last reply
          0
          • SPlattenS SPlatten

            @VRonin said in QListWidget, how to post a question to the user before allowing change?:

            QItemSelectionModel
            I know this is quite old now, I'm looking at implementing this now, in the slot:

            void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) override{
                    askSelect(selection,command);
                }
            

            Is the line askSelect correct? because its a signal in the class, shouldn't it read:

            emit askSelect(selection, command);
            

            ?

            jsulmJ Offline
            jsulmJ Offline
            jsulm
            Lifetime Qt Champion
            wrote on last edited by
            #14

            @SPlatten You don't have to use emit.
            emit is an empty macro and is only used to make clear to the reader of the code that a signal is emitted.
            Also, trying to execute the code is faster than asking in a forum and waiting for an answer :-)

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            4
            • SPlattenS SPlatten

              @VRonin said in QListWidget, how to post a question to the user before allowing change?:

              QItemSelectionModel
              I know this is quite old now, I'm looking at implementing this now, in the slot:

              void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) override{
                      askSelect(selection,command);
                  }
              

              Is the line askSelect correct? because its a signal in the class, shouldn't it read:

              emit askSelect(selection, command);
              

              ?

              J.HilkJ Offline
              J.HilkJ Offline
              J.Hilk
              Moderators
              wrote on last edited by
              #15

              @SPlatten emit ist syntactic sugar, it expands to void. askSelect is a simple function, that has it function body in the *moc file that qmake creates.

              but, yes you can add it :D


              Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


              Q: What's that?
              A: It's blue light.
              Q: What does it do?
              A: It turns blue.

              1 Reply Last reply
              1
              • VRoninV VRonin

                Ok, the problem can be solved with a simple reimplementation of the selection model:

                #include <QItemSelectionModel>
                class AskSelectionModel : public QItemSelectionModel{
                    Q_OBJECT
                    Q_DISABLE_COPY_MOVE(AskSelectionModel)
                public:
                    using QItemSelectionModel::QItemSelectionModel;
                public slots:
                    void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) override{
                        askSelect(selection,command);
                    }
                    virtual void actuallySelect(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command){
                        QItemSelectionModel::select(selection,command);
                    }
                signals:
                    void askSelect(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command);
                };
                
                int main(int argc, char *argv[])
                {
                   QApplication app(argc,argv);
                   QListWidget mainWid;
                   AskSelectionModel* askModel = new AskSelectionModel(mainWid.model(),&mainWid);
                   mainWid.setSelectionMode(QAbstractItemView::ExtendedSelection);
                   mainWid.setSelectionModel(askModel);
                   for(int i=0;i<5;++i)
                       mainWid.addItem(QStringLiteral("Item ") + QString::number(i));
                   QObject::connect(askModel,&AskSelectionModel::askSelect,[&mainWid,askModel](const QItemSelection &selection, QItemSelectionModel::SelectionFlags command){
                       if(QMessageBox::question(&mainWid,QStringLiteral("Are you sure?"),QStringLiteral("Are you sure you want to change the selection?")) == QMessageBox::StandardButton::Yes){
                           askModel->actuallySelect(selection, command);
                       }
                   });
                   mainWid.show();
                   return app.exec();
                }
                
                SPlattenS Offline
                SPlattenS Offline
                SPlatten
                wrote on last edited by SPlatten
                #16

                @VRonin , can you help with this implementation?

                //ABC = Ask Before Change
                QString strABC(mpobjNode->strGetAttribute
                                                (clsXMLnode::mscszAttrAskBeforeChange));
                if ( strABC.isEmpty() != true ) {
                //Use "clsQtAskBeforeChange" to prompt user for confirmation if
                //changes in child nodes before allowing change
                    clsQtAskBeforeChange* pobjABC(new clsQtAskBeforeChange(model(), this));
                    setSelectionMode(QAbstractItemView::ExtendedSelection);
                    setSelectionModel(pobjABC);
                //Now the widget should be set-up, finalise set-up
                    clsXMLinterface::setup();
                //Connect signal
                    clsQtListWidget* pobjThis(this);
                    QObject::connect(pobjABC, &clsQtAskBeforeChange::pendingSelect
                                ,[pobjABC, strABC, pobjThis](const QItemSelection& crobjSelection
                                    ,QItemSelectionModel::SelectionFlags cmdFlags) {
                        if ( QMessageBox::question(pobjThis, QStringLiteral("Please confirm...")
                                , strABC) == QMessageBox::StandardButton::Yes) {
                            pobjABC->actuallySelect(crobjSelection, cmdFlags);
                        }
                    });
                }
                

                The above is in my implementation of QListWidget constructor. On the line that contains:

                QObject::connect(pobjABC, &clsQtAskBeforeChange::pendingSelect
                

                To the right of it I have the message:

                Pass a context object as 3rd connect parameter [clazy-connect-3arg-lambda]
                

                This is cryptic, I don't understand what it is telling me, have I done anything wrong because the code seems to work fine?

                Kind Regards,
                Sy

                JonBJ 1 Reply Last reply
                0
                • SPlattenS SPlatten

                  @VRonin , can you help with this implementation?

                  //ABC = Ask Before Change
                  QString strABC(mpobjNode->strGetAttribute
                                                  (clsXMLnode::mscszAttrAskBeforeChange));
                  if ( strABC.isEmpty() != true ) {
                  //Use "clsQtAskBeforeChange" to prompt user for confirmation if
                  //changes in child nodes before allowing change
                      clsQtAskBeforeChange* pobjABC(new clsQtAskBeforeChange(model(), this));
                      setSelectionMode(QAbstractItemView::ExtendedSelection);
                      setSelectionModel(pobjABC);
                  //Now the widget should be set-up, finalise set-up
                      clsXMLinterface::setup();
                  //Connect signal
                      clsQtListWidget* pobjThis(this);
                      QObject::connect(pobjABC, &clsQtAskBeforeChange::pendingSelect
                                  ,[pobjABC, strABC, pobjThis](const QItemSelection& crobjSelection
                                      ,QItemSelectionModel::SelectionFlags cmdFlags) {
                          if ( QMessageBox::question(pobjThis, QStringLiteral("Please confirm...")
                                  , strABC) == QMessageBox::StandardButton::Yes) {
                              pobjABC->actuallySelect(crobjSelection, cmdFlags);
                          }
                      });
                  }
                  

                  The above is in my implementation of QListWidget constructor. On the line that contains:

                  QObject::connect(pobjABC, &clsQtAskBeforeChange::pendingSelect
                  

                  To the right of it I have the message:

                  Pass a context object as 3rd connect parameter [clazy-connect-3arg-lambda]
                  

                  This is cryptic, I don't understand what it is telling me, have I done anything wrong because the code seems to work fine?

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by JonB
                  #17

                  @SPlatten
                  Although this 3-argument connect() works, it is more usual to pass 4 arguments, with the 3rd argument being the "context" object for the slot's this. That is what the warning is telling you. I believe you can get rid of that via (something like):

                      QObject::connect(pobjABC, &clsQtAskBeforeChange::pendingSelect
                                  , pobjABC, [strABC, pobjThis](const QItemSelection& crobjSelection
                                      ,QItemSelectionModel::SelectionFlags cmdFlags) {
                          if ( QMessageBox::question(pobjThis, QStringLiteral("Please confirm...")
                                  , strABC) == QMessageBox::StandardButton::Yes) {
                              this->actuallySelect(crobjSelection, cmdFlags);
                          }
                      });
                  
                  Christian EhrlicherC 1 Reply Last reply
                  2
                  • JonBJ JonB

                    @SPlatten
                    Although this 3-argument connect() works, it is more usual to pass 4 arguments, with the 3rd argument being the "context" object for the slot's this. That is what the warning is telling you. I believe you can get rid of that via (something like):

                        QObject::connect(pobjABC, &clsQtAskBeforeChange::pendingSelect
                                    , pobjABC, [strABC, pobjThis](const QItemSelection& crobjSelection
                                        ,QItemSelectionModel::SelectionFlags cmdFlags) {
                            if ( QMessageBox::question(pobjThis, QStringLiteral("Please confirm...")
                                    , strABC) == QMessageBox::StandardButton::Yes) {
                                this->actuallySelect(crobjSelection, cmdFlags);
                            }
                        });
                    
                    Christian EhrlicherC Offline
                    Christian EhrlicherC Offline
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote on last edited by
                    #18

                    @JonB Since the lambda accesses this, the third parameter should be this too. Otherwise the disconnect will not be done when this is deleted but pobjABC is still alive.

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

                    JonBJ 1 Reply Last reply
                    3
                    • Christian EhrlicherC Christian Ehrlicher

                      @JonB Since the lambda accesses this, the third parameter should be this too. Otherwise the disconnect will not be done when this is deleted but pobjABC is still alive.

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by JonB
                      #19

                      @Christian-Ehrlicher
                      I'm lost --- where does the (original) lambda access this? The only this is the one I put in for the pobjABC which I have made the context? In the body I replaced pobjABC->actuallySelect() by this->actuallySelect(), for clarity; and I chose pobjABC as the context as it felt like that was the primary slot object there. (I did get this right, didn't I? The slot-context-object, my pobjABC, becomes this in the lambda body?) My thought was to pass that as it won't be disconnected if pobjABC dies. I admit I didn't look terribly closely, I get awfully mixed with all the OP's pobj...s :)

                      Christian EhrlicherC SPlattenS 2 Replies Last reply
                      0
                      • JonBJ JonB

                        @Christian-Ehrlicher
                        I'm lost --- where does the (original) lambda access this? The only this is the one I put in for the pobjABC which I have made the context? In the body I replaced pobjABC->actuallySelect() by this->actuallySelect(), for clarity; and I chose pobjABC as the context as it felt like that was the primary slot object there. (I did get this right, didn't I? The slot-context-object, my pobjABC, becomes this in the lambda body?) My thought was to pass that as it won't be disconnected if pobjABC dies. I admit I didn't look terribly closely, I get awfully mixed with all the OP's pobj...s :)

                        Christian EhrlicherC Offline
                        Christian EhrlicherC Offline
                        Christian Ehrlicher
                        Lifetime Qt Champion
                        wrote on last edited by
                        #20

                        @JonB I only looked at your answer - the slot accesses this and not pobjABC so the signals scope should be this too :)

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

                        1 Reply Last reply
                        0
                        • JonBJ JonB

                          @Christian-Ehrlicher
                          I'm lost --- where does the (original) lambda access this? The only this is the one I put in for the pobjABC which I have made the context? In the body I replaced pobjABC->actuallySelect() by this->actuallySelect(), for clarity; and I chose pobjABC as the context as it felt like that was the primary slot object there. (I did get this right, didn't I? The slot-context-object, my pobjABC, becomes this in the lambda body?) My thought was to pass that as it won't be disconnected if pobjABC dies. I admit I didn't look terribly closely, I get awfully mixed with all the OP's pobj...s :)

                          SPlattenS Offline
                          SPlattenS Offline
                          SPlatten
                          wrote on last edited by SPlatten
                          #21

                          @JonB , pobjABC does become this in the lambda because the connection is created using pobjABC.

                          I've tried various suggestions, however I'm still getting the same result:

                          Pass a context object or 3rd connect parameter [clazy-connect-3ard-lambda]
                          

                          This is gibberish because there are already 3 parameters passed. I even changed the parameters to:

                          [strABC, pobjABC, this, pobjThis]
                          

                          Still get the same message.

                          Kind Regards,
                          Sy

                          Christian EhrlicherC JonBJ 2 Replies Last reply
                          0
                          • SPlattenS SPlatten

                            @JonB , pobjABC does become this in the lambda because the connection is created using pobjABC.

                            I've tried various suggestions, however I'm still getting the same result:

                            Pass a context object or 3rd connect parameter [clazy-connect-3ard-lambda]
                            

                            This is gibberish because there are already 3 parameters passed. I even changed the parameters to:

                            [strABC, pobjABC, this, pobjThis]
                            

                            Still get the same message.

                            Christian EhrlicherC Offline
                            Christian EhrlicherC Offline
                            Christian Ehrlicher
                            Lifetime Qt Champion
                            wrote on last edited by
                            #22

                            @SPlatten said in QListWidget, how to post a question to the user before allowing change?:

                            This is gibberish because there are already 3 parameters passed.

                            This is not gibberish - you only have to read it properly and our answers... you have to pass a context as third parameter, not the lambda (this should be the forth then)

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

                            1 Reply Last reply
                            2
                            • SPlattenS SPlatten

                              @JonB , pobjABC does become this in the lambda because the connection is created using pobjABC.

                              I've tried various suggestions, however I'm still getting the same result:

                              Pass a context object or 3rd connect parameter [clazy-connect-3ard-lambda]
                              

                              This is gibberish because there are already 3 parameters passed. I even changed the parameters to:

                              [strABC, pobjABC, this, pobjThis]
                              

                              Still get the same message.

                              JonBJ Offline
                              JonBJ Offline
                              JonB
                              wrote on last edited by
                              #23

                              @SPlatten
                              I posted mine with a 4th parameter and explained. Did you actually copy it and get the same error message? I don't think so. The issue is the number of parameters to connect(). You are looking at the number of items in the [...] context for the lambda, which is not what the message refers to.

                              SPlattenS 1 Reply Last reply
                              1
                              • JonBJ JonB

                                @SPlatten
                                I posted mine with a 4th parameter and explained. Did you actually copy it and get the same error message? I don't think so. The issue is the number of parameters to connect(). You are looking at the number of items in the [...] context for the lambda, which is not what the message refers to.

                                SPlattenS Offline
                                SPlattenS Offline
                                SPlatten
                                wrote on last edited by
                                #24

                                @JonB , @Christian-Ehrlicher , sorry, it wasn't clear to me at first that the actual 3rd parameter you were referring to was of the connect, I thought it was the 3rd parameter of the lambda set.

                                It was more confusing because when compiled the connect worked without the 3rd parameter. being correct.

                                Kind Regards,
                                Sy

                                JonBJ 1 Reply Last reply
                                0
                                • SPlattenS SPlatten

                                  @JonB , @Christian-Ehrlicher , sorry, it wasn't clear to me at first that the actual 3rd parameter you were referring to was of the connect, I thought it was the 3rd parameter of the lambda set.

                                  It was more confusing because when compiled the connect worked without the 3rd parameter. being correct.

                                  JonBJ Offline
                                  JonBJ Offline
                                  JonB
                                  wrote on last edited by
                                  #25

                                  @SPlatten
                                  Your 3-parameter one should work, the [clazy-connect-3arg-lambda] should be a warning that it can be inadvisable because of lifetime/disconnect behaviour.

                                  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