Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. How to remove items from c++ model inside qml?

How to remove items from c++ model inside qml?

Scheduled Pinned Locked Moved QML and Qt Quick
qmlqtquickmvcmodel
38 Posts 3 Posters 16.7k 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.
  • C CoderJeff

    @p3c0 said:

    @CoderJeff Are you sure tableView.currentRow returns a valid row ?

    Yes, I debug my code, and the input parameter idx is correct.

    There are six rows. I checked each row's index: 0,1,2,3,4,5.

    p3c0P Offline
    p3c0P Offline
    p3c0
    Moderators
    wrote on last edited by
    #9

    @CoderJeff Ok. Not sure then. I guess there's some other code that is causing the problem.

    157

    C 1 Reply Last reply
    0
    • p3c0P p3c0

      @CoderJeff Ok. Not sure then. I guess there's some other code that is causing the problem.

      C Offline
      C Offline
      CoderJeff
      wrote on last edited by
      #10

      @p3c0

      The entire code is the following.

      In C++ (Q_INVOKABLE):
      void MyCppClass::remove(const int idx)
      {
      bool bExe = mySqlModel->removeRow(idx);
      }

      (Q_INVOKABLE)
      QObject* MyCppClass::selectModel()
      {
      return mySqlModel->selectModel();
      }

      MySqlModel* MySqlModel::selectModel()
      {
      QString strQuery("SELECT field1,field2,field3 FROM table WHERE field1='a'");
      setQuery(QSqlQuery(strQuery));
      return this;
      }

      TableView {
      id: tableView
      TableViewColumn{ role: "field1"; title: "Field1"}
      TableViewColumn{ role: "field2"; title: "Field2"}
      TableViewColumn{ role: "field3"; title: "Field3"}
      model: myCppClass.selectModel()
      ......
      }

      Button{
      onClicked: myCppClass.remove(tableView.currentRow);
      }

      p3c0P 1 Reply Last reply
      0
      • C CoderJeff

        @p3c0

        The entire code is the following.

        In C++ (Q_INVOKABLE):
        void MyCppClass::remove(const int idx)
        {
        bool bExe = mySqlModel->removeRow(idx);
        }

        (Q_INVOKABLE)
        QObject* MyCppClass::selectModel()
        {
        return mySqlModel->selectModel();
        }

        MySqlModel* MySqlModel::selectModel()
        {
        QString strQuery("SELECT field1,field2,field3 FROM table WHERE field1='a'");
        setQuery(QSqlQuery(strQuery));
        return this;
        }

        TableView {
        id: tableView
        TableViewColumn{ role: "field1"; title: "Field1"}
        TableViewColumn{ role: "field2"; title: "Field2"}
        TableViewColumn{ role: "field3"; title: "Field3"}
        model: myCppClass.selectModel()
        ......
        }

        Button{
        onClicked: myCppClass.remove(tableView.currentRow);
        }

        p3c0P Offline
        p3c0P Offline
        p3c0
        Moderators
        wrote on last edited by
        #11

        @CoderJeff Can you check if mySqlModel has data ?
        You can check it by using record.

        mySqlModel->record(idx).value(0).toString() // checking value at column 0 and converting it to string
        

        157

        C 2 Replies Last reply
        0
        • p3c0P p3c0

          @CoderJeff Can you check if mySqlModel has data ?
          You can check it by using record.

          mySqlModel->record(idx).value(0).toString() // checking value at column 0 and converting it to string
          
          C Offline
          C Offline
          CoderJeff
          wrote on last edited by
          #12

          @p3c0

          You are right. It is empty.

          I will check the logic.

          1 Reply Last reply
          0
          • p3c0P p3c0

            @CoderJeff Can you check if mySqlModel has data ?
            You can check it by using record.

            mySqlModel->record(idx).value(0).toString() // checking value at column 0 and converting it to string
            
            C Offline
            C Offline
            CoderJeff
            wrote on last edited by p3c0
            #13

            @p3c0

            A weird phenomenon. If using QSqlTableModel, the result is invalid. But if using QSqlQueryModel, the result is the expected.

            Why?

            The following is my debugging code.

            MySqlModel* MySqlModel::selectModel()
            {
            QString strQuery("SELECT field1,field2,field3 FROM table WHERE field1='a'");
            
                QVariant val0;
                QVariant val1;
            
                setQuery(QSqlQuery(strQuery));
                val0 =  record(0).value(0);  //Invalid
                val1 =  record(0).value(1);  //Invalid
            
                QSqlQueryModel model;
                model.setQuery(strQuery);
                val0 =  model.record(0).value(0);  //Correct. The result is the expected.
                val1 =  model.record(0).value(1);  //Correct. The result is the expected.
            
            return this;
            }
            
            p3c0P 1 Reply Last reply
            0
            • C CoderJeff

              @p3c0

              A weird phenomenon. If using QSqlTableModel, the result is invalid. But if using QSqlQueryModel, the result is the expected.

              Why?

              The following is my debugging code.

              MySqlModel* MySqlModel::selectModel()
              {
              QString strQuery("SELECT field1,field2,field3 FROM table WHERE field1='a'");
              
                  QVariant val0;
                  QVariant val1;
              
                  setQuery(QSqlQuery(strQuery));
                  val0 =  record(0).value(0);  //Invalid
                  val1 =  record(0).value(1);  //Invalid
              
                  QSqlQueryModel model;
                  model.setQuery(strQuery);
                  val0 =  model.record(0).value(0);  //Correct. The result is the expected.
                  val1 =  model.record(0).value(1);  //Correct. The result is the expected.
              
              return this;
              }
              
              p3c0P Offline
              p3c0P Offline
              p3c0
              Moderators
              wrote on last edited by p3c0
              #14

              @CoderJeff According to the doc here, setTable should be used instead of setQuery for QSqlTableModel.

              157

              C 1 Reply Last reply
              0
              • p3c0P p3c0

                @CoderJeff According to the doc here, setTable should be used instead of setQuery for QSqlTableModel.

                C Offline
                C Offline
                CoderJeff
                wrote on last edited by CoderJeff
                #15

                @p3c0 said:

                @CoderJeff According to the doc here, setTable should be used instead of setQuery for QSqlTableModel.

                The cause is not as simple as I expected. Although I change MySqlModel's parent class to QSqlQueryModel instead of QSqlTableModel, it still does not work. But if using QSqlQueryModel directly, it works.

                I am confusing.

                class MySqlModel : public QSqlQueryModel
                {
                }

                MySqlModel* MySqlModel::selectModel()
                {
                QString strQuery("SELECT field1,field2,field3 FROM table WHERE field1='a'");

                QVariant val0;
                QVariant val1;
                
                //using MySqlQueryModel
                setQuery(strQuery);
                val0 =  record(0).value(0);  //Invalid
                val1 =  record(0).value(1);  //Invalid
                
                //using QSqlQueryModel directly
                QSqlQueryModel model;
                model.setQuery(strQuery);
                val0 =  model.record(0).value(0);  //Correct. The result is the expected.
                val1 =  model.record(0).value(1);  //Correct. The result is the expected.
                

                return this;
                }

                p3c0P 1 Reply Last reply
                0
                • C CoderJeff

                  @p3c0 said:

                  @CoderJeff According to the doc here, setTable should be used instead of setQuery for QSqlTableModel.

                  The cause is not as simple as I expected. Although I change MySqlModel's parent class to QSqlQueryModel instead of QSqlTableModel, it still does not work. But if using QSqlQueryModel directly, it works.

                  I am confusing.

                  class MySqlModel : public QSqlQueryModel
                  {
                  }

                  MySqlModel* MySqlModel::selectModel()
                  {
                  QString strQuery("SELECT field1,field2,field3 FROM table WHERE field1='a'");

                  QVariant val0;
                  QVariant val1;
                  
                  //using MySqlQueryModel
                  setQuery(strQuery);
                  val0 =  record(0).value(0);  //Invalid
                  val1 =  record(0).value(1);  //Invalid
                  
                  //using QSqlQueryModel directly
                  QSqlQueryModel model;
                  model.setQuery(strQuery);
                  val0 =  model.record(0).value(0);  //Correct. The result is the expected.
                  val1 =  model.record(0).value(1);  //Correct. The result is the expected.
                  

                  return this;
                  }

                  p3c0P Offline
                  p3c0P Offline
                  p3c0
                  Moderators
                  wrote on last edited by
                  #16

                  @CoderJeff Make sure the query is active before using setQuery.

                  QSqlQuery sq;
                  sq.prepare(strQuery);
                  sq.exec();
                  qDebug() << sq.isActive();
                  setQuery(sq);
                  

                  157

                  C 1 Reply Last reply
                  0
                  • p3c0P p3c0

                    @CoderJeff Make sure the query is active before using setQuery.

                    QSqlQuery sq;
                    sq.prepare(strQuery);
                    sq.exec();
                    qDebug() << sq.isActive();
                    setQuery(sq);
                    
                    C Offline
                    C Offline
                    CoderJeff
                    wrote on last edited by
                    #17

                    @p3c0 said:

                    @CoderJeff Make sure the query is active before using setQuery.

                    QSqlQuery sq;
                    sq.prepare(strQuery);
                    sq.exec();
                    qDebug() << sq.isActive();
                    setQuery(sq);
                    

                    I tested it in your way, but It still did not work. The query is definitely active because the return value of isActive() is true.

                    p3c0P 1 Reply Last reply
                    0
                    • C CoderJeff

                      @p3c0 said:

                      @CoderJeff Make sure the query is active before using setQuery.

                      QSqlQuery sq;
                      sq.prepare(strQuery);
                      sq.exec();
                      qDebug() << sq.isActive();
                      setQuery(sq);
                      

                      I tested it in your way, but It still did not work. The query is definitely active because the return value of isActive() is true.

                      p3c0P Offline
                      p3c0P Offline
                      p3c0
                      Moderators
                      wrote on last edited by p3c0
                      #18

                      @CoderJeff Ok. Can you post your complete minimal runnable code somewhere in a zip to test ? Need to check whats actually going on.

                      157

                      C 1 Reply Last reply
                      0
                      • p3c0P p3c0

                        @CoderJeff Ok. Can you post your complete minimal runnable code somewhere in a zip to test ? Need to check whats actually going on.

                        C Offline
                        C Offline
                        CoderJeff
                        wrote on last edited by
                        #19

                        @p3c0 said:

                        @CoderJeff Ok. Can you post your complete minimal runnable code somewhere in a zip to test ? Need to check whats actually going on.

                        I sent you the link. Please check it.

                        p3c0P 1 Reply Last reply
                        0
                        • C CoderJeff

                          @p3c0 said:

                          @CoderJeff Ok. Can you post your complete minimal runnable code somewhere in a zip to test ? Need to check whats actually going on.

                          I sent you the link. Please check it.

                          p3c0P Offline
                          p3c0P Offline
                          p3c0
                          Moderators
                          wrote on last edited by p3c0
                          #20

                          Hi @CoderJeff,
                          Your code looks fine. Use method1 or method3 in MySqlModel. The problem is with the view. TableView inside ScrollView seems to break. I just kept TableView in tab01 and everything worked as expected.

                          157

                          C 1 Reply Last reply
                          0
                          • p3c0P p3c0

                            Hi @CoderJeff,
                            Your code looks fine. Use method1 or method3 in MySqlModel. The problem is with the view. TableView inside ScrollView seems to break. I just kept TableView in tab01 and everything worked as expected.

                            C Offline
                            C Offline
                            CoderJeff
                            wrote on last edited by CoderJeff
                            #21

                            @p3c0 said:

                            Hi @CoderJeff,
                            Your code looks fine. Use method1 or method3 in MySqlModel. The problem is with the view. TableView inside ScrollView seems to break. I just kept TableView in tab01 and everything worked as expected.

                            What's the meaning of "kept TableView in tab01"? Can you show me the code?

                            p3c0P 1 Reply Last reply
                            0
                            • C CoderJeff

                              @p3c0 said:

                              Hi @CoderJeff,
                              Your code looks fine. Use method1 or method3 in MySqlModel. The problem is with the view. TableView inside ScrollView seems to break. I just kept TableView in tab01 and everything worked as expected.

                              What's the meaning of "kept TableView in tab01"? Can you show me the code?

                              p3c0P Offline
                              p3c0P Offline
                              p3c0
                              Moderators
                              wrote on last edited by
                              #22

                              @CoderJeff The contents of tab01.qml file. I just TableView in it and deleted the rest. It works.

                              //Tab01.qml
                              
                              import QtQuick 2.0
                              import QtQuick.Controls 1.2
                              import QtQuick.Layouts 1.1
                              
                              TableView{
                                  id: tableView
                                  anchors.fill: parent
                                  TableViewColumn{ role: "id"; title: "Id"}
                                  TableViewColumn{ role: "name"; title: "Name"}
                                  TableViewColumn{ role: "author"; title: "Author"}
                                  TableViewColumn{ role: "year"; title: "Year"}
                                  model:myCppClass.model()
                              }
                              

                              157

                              C 1 Reply Last reply
                              0
                              • p3c0P p3c0

                                @CoderJeff The contents of tab01.qml file. I just TableView in it and deleted the rest. It works.

                                //Tab01.qml
                                
                                import QtQuick 2.0
                                import QtQuick.Controls 1.2
                                import QtQuick.Layouts 1.1
                                
                                TableView{
                                    id: tableView
                                    anchors.fill: parent
                                    TableViewColumn{ role: "id"; title: "Id"}
                                    TableViewColumn{ role: "name"; title: "Name"}
                                    TableViewColumn{ role: "author"; title: "Author"}
                                    TableViewColumn{ role: "year"; title: "Year"}
                                    model:myCppClass.model()
                                }
                                
                                C Offline
                                C Offline
                                CoderJeff
                                wrote on last edited by
                                #23

                                @p3c0

                                I got it.

                                Yes, it works. I change ScrollView to Rectangle, and it also seems work well. But I debugged the code, and fount that the value of val0 and val1 in method1 and method3 were still not right.

                                Did you check them?

                                p3c0P 2 Replies Last reply
                                0
                                • C CoderJeff

                                  @p3c0

                                  I got it.

                                  Yes, it works. I change ScrollView to Rectangle, and it also seems work well. But I debugged the code, and fount that the value of val0 and val1 in method1 and method3 were still not right.

                                  Did you check them?

                                  p3c0P Offline
                                  p3c0P Offline
                                  p3c0
                                  Moderators
                                  wrote on last edited by
                                  #24

                                  @CoderJeff Hmm that's strange. It doesn't work. Tested it with my other project, works there.

                                  157

                                  C 1 Reply Last reply
                                  0
                                  • C CoderJeff

                                    @p3c0

                                    I got it.

                                    Yes, it works. I change ScrollView to Rectangle, and it also seems work well. But I debugged the code, and fount that the value of val0 and val1 in method1 and method3 were still not right.

                                    Did you check them?

                                    p3c0P Offline
                                    p3c0P Offline
                                    p3c0
                                    Moderators
                                    wrote on last edited by
                                    #25

                                    @CoderJeff If you replace the code in data() with the following, it will work:

                                    QVariant MySqlModel::data(const QModelIndex &index, int role) const
                                    {
                                        if (!index.isValid())
                                            return QVariant();
                                    
                                        switch(role) {
                                            case Id: {
                                                return record(index.row()).value(0).toString();
                                            }
                                            case Name : {
                                                return record(index.row()).value(1).toString();
                                            }
                                            case Author : {
                                                return record(index.row()).value(2).toString();
                                            }
                                            case Year : {
                                                return record(index.row()).value(3).toString();
                                            }
                                        }
                                        return QSqlQueryModel::data(index, role);
                                    }
                                    
                                    ...
                                    
                                    setQuery(strQuery);
                                    var0 = record(1).value(0);
                                    var1 = record(0).value(1);
                                    qDebug() << var0 << var1;
                                    

                                    Trying to find the reason.

                                    157

                                    C 1 Reply Last reply
                                    0
                                    • p3c0P p3c0

                                      @CoderJeff Hmm that's strange. It doesn't work. Tested it with my other project, works there.

                                      C Offline
                                      C Offline
                                      CoderJeff
                                      wrote on last edited by
                                      #26

                                      @p3c0

                                      That's what I am confused with. In addition, I tested the following statements, and they all works.

                                      record(0).indexof(...)
                                      record(0).index(...)
                                      data(...)

                                      I do not understand why only record(0).value(...) can not work.

                                      I tried to delete a chosen row, but it could not.I do not know whether it is the above reason. I have updated my code. Can you please check them? Thank you.

                                      1 Reply Last reply
                                      0
                                      • p3c0P p3c0

                                        @CoderJeff If you replace the code in data() with the following, it will work:

                                        QVariant MySqlModel::data(const QModelIndex &index, int role) const
                                        {
                                            if (!index.isValid())
                                                return QVariant();
                                        
                                            switch(role) {
                                                case Id: {
                                                    return record(index.row()).value(0).toString();
                                                }
                                                case Name : {
                                                    return record(index.row()).value(1).toString();
                                                }
                                                case Author : {
                                                    return record(index.row()).value(2).toString();
                                                }
                                                case Year : {
                                                    return record(index.row()).value(3).toString();
                                                }
                                            }
                                            return QSqlQueryModel::data(index, role);
                                        }
                                        
                                        ...
                                        
                                        setQuery(strQuery);
                                        var0 = record(1).value(0);
                                        var1 = record(0).value(1);
                                        qDebug() << var0 << var1;
                                        

                                        Trying to find the reason.

                                        C Offline
                                        C Offline
                                        CoderJeff
                                        wrote on last edited by
                                        #27

                                        @p3c0 said:

                                        @CoderJeff If you replace the code in data() with the following, it will work:

                                        QVariant MySqlModel::data(const QModelIndex &index, int role) const
                                        {
                                            if (!index.isValid())
                                                return QVariant();
                                        
                                            switch(role) {
                                                case Id: {
                                                    return record(index.row()).value(0).toString();
                                                }
                                                case Name : {
                                                    return record(index.row()).value(1).toString();
                                                }
                                                case Author : {
                                                    return record(index.row()).value(2).toString();
                                                }
                                                case Year : {
                                                    return record(index.row()).value(3).toString();
                                                }
                                            }
                                            return QSqlQueryModel::data(index, role);
                                        }
                                        
                                        ...
                                        
                                        setQuery(strQuery);
                                        var0 = record(1).value(0);
                                        var1 = record(0).value(1);
                                        qDebug() << var0 << var1;
                                        

                                        Trying to find the reason.

                                        Yes, it works. The value of val0 and val1 are both right this time. But I still can not delete a row.

                                        p3c0P 1 Reply Last reply
                                        0
                                        • C CoderJeff

                                          @p3c0 said:

                                          @CoderJeff If you replace the code in data() with the following, it will work:

                                          QVariant MySqlModel::data(const QModelIndex &index, int role) const
                                          {
                                              if (!index.isValid())
                                                  return QVariant();
                                          
                                              switch(role) {
                                                  case Id: {
                                                      return record(index.row()).value(0).toString();
                                                  }
                                                  case Name : {
                                                      return record(index.row()).value(1).toString();
                                                  }
                                                  case Author : {
                                                      return record(index.row()).value(2).toString();
                                                  }
                                                  case Year : {
                                                      return record(index.row()).value(3).toString();
                                                  }
                                              }
                                              return QSqlQueryModel::data(index, role);
                                          }
                                          
                                          ...
                                          
                                          setQuery(strQuery);
                                          var0 = record(1).value(0);
                                          var1 = record(0).value(1);
                                          qDebug() << var0 << var1;
                                          

                                          Trying to find the reason.

                                          Yes, it works. The value of val0 and val1 are both right this time. But I still can not delete a row.

                                          p3c0P Offline
                                          p3c0P Offline
                                          p3c0
                                          Moderators
                                          wrote on last edited by
                                          #28

                                          @CoderJeff That is because QSqlquerymodel is a read-only model. See here. You will need to delete the row using another query and then update the view.

                                          157

                                          C 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