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. Implementing QAbstractTableModel
Forum Updated to NodeBB v4.3 + New Features

Implementing QAbstractTableModel

Scheduled Pinned Locked Moved General and Desktop
23 Posts 4 Posters 13.7k Views 1 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.
  • P Offline
    P Offline
    portoist
    wrote on last edited by
    #7

    Well i'v been using this "example":http://doc.qt.nokia.com/4.7-snapshot/declarative-modelviews-abstractitemmodel.html, my data method is following:
    @
    QVariant myTable::data(const QModelIndex &index, int role) const {
    cout<<"Data called with col: "<<index.column()<<" row:"<<index.row()<<endl;
    if (this->m_data.count() <= 0){
    return QVariant();
    }
    QList<QString> tmpList = this->m_data[index.row()];
    QString res = tmpList[index.column()];
    return res;
    }
    @

    1 Reply Last reply
    0
    • G Offline
      G Offline
      giesbert
      wrote on last edited by
      #8

      You MUST check the role. typically, you implement it for display role and leave all the rest as is (means call base method).
      How are your rowCount and columnCount methods implemented?

      This all must fit together, so just showing one block of the code is not enough...

      Nokia Certified Qt Specialist.
      Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

      1 Reply Last reply
      0
      • P Offline
        P Offline
        portoist
        wrote on last edited by
        #9

        My rowCount and columnCount methods are following:
        @
        int myTable::rowCount(const QModelIndex &parent) const{
        return this->m_data.count();
        }

        int myTable::columnCount(const QModelIndex &parent) const{
        if (this->m_data.count() <= 0){
        return 0;
        }
        return this->m_data[0].count();
        }
        @

        I wasn't checking role in data method because i got only one role, this is how constructor looks like:
        @
        myTable::myTable(QObject *parent) : QAbstractTableModel(parent){
        QHash<int, QByteArray> roles;
        roles[valueRole] = "value";
        setRoleNames(roles);
        }
        @

        1 Reply Last reply
        0
        • D Offline
          D Offline
          dmcr
          wrote on last edited by
          #10

          At second glance I would have called beginInsertXXXX() and endInsertXXXX() the number of XXXX inserted, namely in the two for{...}

          dmcr

          1 Reply Last reply
          0
          • P Offline
            P Offline
            portoist
            wrote on last edited by
            #11

            That ends up with runtime error:
            terminate called after throwing an instance of 'std::bad_alloc'
            what(): std::bad_alloc
            The program has unexpectedly finished

            1 Reply Last reply
            0
            • D Offline
              D Offline
              dmcr
              wrote on last edited by
              #12

              To be honnest i don't like to use QByteArray : this object is designed for network exchange, not for display.
              I would first create some QString from your QByteArrays, then implement the display of your table with it....

              dmcr

              1 Reply Last reply
              0
              • P Offline
                P Offline
                portoist
                wrote on last edited by
                #13

                Well, I am not sure if i understand you. I am using QList< QList<QString> > and i am displaying QString. The thing is, that data method gets called just once with index 0,0 and value stored in QList on this index is displayed just fine, but others are not, since data method is not called anymore...
                ie:
                QList< QList<QString> > my_data is filled with following
                1 2
                3 4
                In main.qml i got following:
                @
                MyModel{
                id: varModel
                dataId: "matrix"
                }

                GridView{
                id: grid
                model: varModel
                delegate: {
                Text{
                text: value
                }
                }
                }
                @

                Method data gets called just once with index 0,0 and value 1 which is on this index is displayed fine, others are not...

                1 Reply Last reply
                0
                • G Offline
                  G Offline
                  giesbert
                  wrote on last edited by
                  #14

                  Hi portoise,

                  could you post some minimal example so we can just debug the problem?
                  That would make it easier. Or did you try to debug on your own?
                  What is really returned in rowCount / columnCount/ flags etc.?

                  Nokia Certified Qt Specialist.
                  Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    andre
                    wrote on last edited by
                    #15

                    I really don't like your design at all. Please considder "my docnote":http://developer.qt.nokia.com/doc/qt-4.7/model-view-programming.html#note-13 on designing your own QAbstractItemModels.

                    I think you first need to define a data store object that handles your blob of data, and supplies a sane API to query it. Only then, you create a QAbstractItemModel (or QAbstractTableModel, in your case) that works on top of that data store. The model is only used as an interface between the Qt item views and your internal data store. It is not suitable as a general data store, I think. The data itself should not be contained within the model.

                    1 Reply Last reply
                    0
                    • D Offline
                      D Offline
                      dmcr
                      wrote on last edited by
                      #16

                      Still in myTable::setValues(QByteArray &values) you use QByte Array.

                      dmcr

                      1 Reply Last reply
                      0
                      • P Offline
                        P Offline
                        portoist
                        wrote on last edited by
                        #17

                        Here is link to my project on dropbox: "Test":http://dl.dropbox.com/u/44811245/Test.tar.gz
                        It reads data from text file specified in constructor of DeviceControll class. Data in file should be in following format: "dataId : rowCount colCount values", values should be separated by space. ie: "myMatrix: 2 2 1 2 3 4".

                        Andre, thanks for your reply and link to your docnote. It explained a lot to me, now i get how model should be used and next time i will stick to that!;-)

                        This "project" is just my playground and I'v followed example that I'v linked above.

                        1 Reply Last reply
                        0
                        • G Offline
                          G Offline
                          giesbert
                          wrote on last edited by
                          #18

                          hi portoist,
                          I found one point:

                          @
                          QVariant myTable::data(const QModelIndex &index, int role) const
                          {
                          if (role != valueRole){
                          return QVariant();
                          }
                          ...
                          }
                          @

                          this should not be, as you return for each role other than value role.
                          Try this code for the model data function:

                          @
                          QVariant myTable::data(const QModelIndex &index, int role) const
                          {
                          if(index.isValid())
                          {
                          cout<<"Data called with column:"<<index.column()<<" row:"<<index.row()<<endl;
                          if(Qt::DisplayRole == role)
                          {
                          if (this->m_data.count() <= 0){
                          return QVariant();
                          }
                          QList<QString> tmpLists = this->m_data[index.row()];
                          QString s = tmpLists[index.column()];
                          cout << "Data will return: "<<s.toLocal8Bit().data()<<endl;
                          return s;
                          }
                          }
                          return QAbstractTableModel::data(index, role);
                          }
                          @

                          Nokia Certified Qt Specialist.
                          Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                          1 Reply Last reply
                          0
                          • P Offline
                            P Offline
                            portoist
                            wrote on last edited by
                            #19

                            Hmm thanks, i'v missed that! But:
                            @
                            return QAbstractTableModel::data(index, role);
                            @
                            will not work as it is virtual method.

                            1 Reply Last reply
                            0
                            • A Offline
                              A Offline
                              andre
                              wrote on last edited by
                              #20

                              Indeed, it is pure virtual (normal virtual methods would work, of course). I guess this was just a matter of habbit from Gerolf to call base implementations as the default case; and a good habbit that is too! :-)

                              1 Reply Last reply
                              0
                              • G Offline
                                G Offline
                                giesbert
                                wrote on last edited by
                                #21

                                [quote author="Andre" date="1318239693"]Indeed, it is pure virtual (normal virtual methods would work, of course). I guess this was just a matter of habbit from Gerolf to call base implementations as the default case; and a good habbit that is too! :-)[/quote]

                                aeh, yep, I did not test it otherwise I would have seen that :-) sorry.
                                a return of an empty variant should be it.

                                Nokia Certified Qt Specialist.
                                Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                                1 Reply Last reply
                                0
                                • P Offline
                                  P Offline
                                  portoist
                                  wrote on last edited by
                                  #22

                                  Well, it still doesn't solve my problem :-) How can I tell to the view that data are invalid? When I am using just simple List, I just call beginInsertRows and endInsertRows. It works ok and data method is requested for row 0,1,2.
                                  I have tried calling beginResetModel each time before values are set but all it does is that it calls data method once with index of column 0 and row 0.
                                  I gues I will have to use just simple list of QString and return whole rows in data method...

                                  1 Reply Last reply
                                  0
                                  • G Offline
                                    G Offline
                                    giesbert
                                    wrote on last edited by
                                    #23

                                    In genereal, it works with beginResetModel / endResetModel if you change the whole model.
                                    If you update a value, use dataChanged signal.
                                    If you only insert a row or a column, use beginInsertRows() and endInsertRows, resp. Columns.

                                    Nokia Certified Qt Specialist.
                                    Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                                    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