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. get the content from a tableview and change it

get the content from a tableview and change it

Scheduled Pinned Locked Moved Unsolved General and Desktop
14 Posts 3 Posters 1.3k 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.
  • M Offline
    M Offline
    Mogli123
    wrote on last edited by Mogli123
    #1

    Hi,

    I'm new in Qt and c++.
    I want get the content of a cell and if the requirement is true i will change the content in the tableview.
    But I make something wrong but I don't know wat exactly.

    there I'm getting the background color of the cell and it works fine

    QVariant TableCustomise::data(const QModelIndex &index, int role) const
    {
        if(role == Qt::BackgroundRole )
        {
    
        QString content = index.sibling(index.row(), 0).data(Qt::DisplayRole).toString();
            if ( content == "red" )
            {
                return QBrush(Qt::red);
            }
        }
    
        return QSqlQueryModel::data(index, role);
    }
    

    therefore I thried to change the content of the cell the same way
    but this doesn't work
    why?

    QVariant TableCustomise::data(const QModelIndex &index, int role)const
    {
            if(role == Qt::DisplayRole())
            {
                QString content = index.sibling(index.row(), index.column()).data(Qt::DisplayRole).toString();
                if (content == "1")
                {
                       return "red";
                }
            }
        return QSqlQueryModel::data(index, role) ;
    }
    

    I hope someone can help me.

    Thank you

    JonBJ 1 Reply Last reply
    0
    • M Mogli123

      Hi,

      I'm new in Qt and c++.
      I want get the content of a cell and if the requirement is true i will change the content in the tableview.
      But I make something wrong but I don't know wat exactly.

      there I'm getting the background color of the cell and it works fine

      QVariant TableCustomise::data(const QModelIndex &index, int role) const
      {
          if(role == Qt::BackgroundRole )
          {
      
          QString content = index.sibling(index.row(), 0).data(Qt::DisplayRole).toString();
              if ( content == "red" )
              {
                  return QBrush(Qt::red);
              }
          }
      
          return QSqlQueryModel::data(index, role);
      }
      

      therefore I thried to change the content of the cell the same way
      but this doesn't work
      why?

      QVariant TableCustomise::data(const QModelIndex &index, int role)const
      {
              if(role == Qt::DisplayRole())
              {
                  QString content = index.sibling(index.row(), index.column()).data(Qt::DisplayRole).toString();
                  if (content == "1")
                  {
                         return "red";
                  }
              }
          return QSqlQueryModel::data(index, role) ;
      }
      

      I hope someone can help me.

      Thank you

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

      @Mogli123
      In your QSqlQueryModel::data(), when you start looking at another cell in order to determine the result for one cell you have to be very careful. And that's your problem here!

      In your working example, to return a cell's Qt::BackgroundRole you look at another cell's Qt::DisplayRole, and that's OK.

      However, in your second example to return a cell's Qt::DisplayRole you look at another cell's Qt::DisplayRole, the same role. Now if you think about it, that causes a potentially "infinite recursion", because when you look at the other cell's Qt::DisplayRole you will be re-executing the same pathway in your TableCustomise::data(), and that in turn will look at that cell's sibling, and so on....

      The first, most obvious problem is that when you come to look at the right-most cell, your code still asks for that one's sibling(), but there isn't one. http://doc.qt.io/qt-5/qmodelindex.html#sibling :

      Returns the sibling at column for the current row. If there is no sibling at this position, an invalid QModelIndex is returned.

      So you must check for your index.sibling(index.row(), index.column()) returning invalid, which you are not presently doing.

      Beyond that, you need to think out what you want here. You keep saying that each cell's Qt::DisplayRole depends on its sibling's Qt::DisplayRole value. That can't be right: it needs to stop somewhere. Perhaps this only applies where index.column() has a certain value?

      There are other approaches which may help. But since you're a beginner I won't go into them yet, don't want to overload you with information. And it may not be necessary, depending on what you wish to change your code to do.

      Let us know!

      1 Reply Last reply
      1
      • M Offline
        M Offline
        Mogli123
        wrote on last edited by Mogli123
        #3

        Thank you for your answer

        I want only know what the content of the cells from each row is.
        Than I decide which color get the background of the complet row.
        Therefore I want to write the color in the first column

        Furthermore is it possible to split the two funktions above?
        I dont't want the two code in the same method

        JonBJ 1 Reply Last reply
        0
        • M Mogli123

          Thank you for your answer

          I want only know what the content of the cells from each row is.
          Than I decide which color get the background of the complet row.
          Therefore I want to write the color in the first column

          Furthermore is it possible to split the two funktions above?
          I dont't want the two code in the same method

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

          @Mogli123
          I'm afraid I don't understand what you are saying in the 3 line-paragraph in your response. So it's difficult to answer! If you are saying you only want "red" returned when index.column() == 0 then you need code for that for a start.

          For the 2 line-paragraph: I think you are saying that when trying to return the Qt::DisplayRole of "red" for a cell, you would rather not have to call the same TableCustomise::data() code to read the Qt::DisplayRole of the sibling, which is what causes the potential recursion?

          Unfortunately, so far as I know once you have written a QSqlQueryModel::data() override you cannot help but have that called to query all cells' data --- there is no way to call another cell's base QSqlQueryModel::data() instead of your overridden method. Because that would have made it easier....

          Unless a C++ expert knows better, the way I can think of to do this is: You can define your own, additional roles. They start at something like Qt::UserRole + 1, or something like that, it's in the docs. I would define that, and have your TableCustomise::data() if called with that as role go

          if (role == Qt::UserRole + 1)
              return QSqlQueryModel::data(index, Qt::DisplayRole);
          

          The intention is that route should return the original display-role value, not the one altered by your override, so no recursion/alteration. You'll have to check this, as I'm not a C++-er.

          Then when looking for the sibling's value you can go

          if (role == Qt::DisplayRole())
          {
              QString content = index.sibling(index.row(), index.column()).data(Qt::UserRole + 1).toString();
              ....
          }
          

          That's assuming this is what you mean by

          Furthermore is it possible to split the two funktions above?
          I dont't want the two code in the same method

          Sorry, I know you're a beginner, you'll have to do a bit of work to read & implement what I've written. Because I don't have time, I really must get on with my own work....!

          VRoninV 1 Reply Last reply
          0
          • JonBJ JonB

            @Mogli123
            I'm afraid I don't understand what you are saying in the 3 line-paragraph in your response. So it's difficult to answer! If you are saying you only want "red" returned when index.column() == 0 then you need code for that for a start.

            For the 2 line-paragraph: I think you are saying that when trying to return the Qt::DisplayRole of "red" for a cell, you would rather not have to call the same TableCustomise::data() code to read the Qt::DisplayRole of the sibling, which is what causes the potential recursion?

            Unfortunately, so far as I know once you have written a QSqlQueryModel::data() override you cannot help but have that called to query all cells' data --- there is no way to call another cell's base QSqlQueryModel::data() instead of your overridden method. Because that would have made it easier....

            Unless a C++ expert knows better, the way I can think of to do this is: You can define your own, additional roles. They start at something like Qt::UserRole + 1, or something like that, it's in the docs. I would define that, and have your TableCustomise::data() if called with that as role go

            if (role == Qt::UserRole + 1)
                return QSqlQueryModel::data(index, Qt::DisplayRole);
            

            The intention is that route should return the original display-role value, not the one altered by your override, so no recursion/alteration. You'll have to check this, as I'm not a C++-er.

            Then when looking for the sibling's value you can go

            if (role == Qt::DisplayRole())
            {
                QString content = index.sibling(index.row(), index.column()).data(Qt::UserRole + 1).toString();
                ....
            }
            

            That's assuming this is what you mean by

            Furthermore is it possible to split the two funktions above?
            I dont't want the two code in the same method

            Sorry, I know you're a beginner, you'll have to do a bit of work to read & implement what I've written. Because I don't have time, I really must get on with my own work....!

            VRoninV Offline
            VRoninV Offline
            VRonin
            wrote on last edited by
            #5

            2 minor notes:
            index.sibling(index.row(), index.column()) is index

            @JonB said in get the content from a tableview and change it:

            there is no way to call another cell's base QSqlQueryModel::data() instead of your overridden method.

            There is and you are using it 2 rows below QSqlQueryModel::data(index, Qt::DisplayRole);

            "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

            JonBJ 1 Reply Last reply
            1
            • VRoninV VRonin

              2 minor notes:
              index.sibling(index.row(), index.column()) is index

              @JonB said in get the content from a tableview and change it:

              there is no way to call another cell's base QSqlQueryModel::data() instead of your overridden method.

              There is and you are using it 2 rows below QSqlQueryModel::data(index, Qt::DisplayRole);

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

              @VRonin

              index.sibling(index.row(), index.column()) is index

              What does this mean? QModelIndex::sibling() returns some (next?) "sibling" of index, no (err, now I wonder..)? I said the OP that he must check that is valid.

              QSqlQueryModel::data(index, Qt::DisplayRole);

              I'm getting lost here in C++ vs the Python I have to use for PyQt/Qt. I thought this would still call his TableCustomise::data() override on the cell specified by index, no? I'm sure when I tried this via PyQt (we can't use the same syntax as C++, and we cannot directly call C++ function, only their PyQt wrappers) it did.... :(

              VRoninV 1 Reply Last reply
              0
              • M Offline
                M Offline
                Mogli123
                wrote on last edited by
                #7

                sorry my enlish ist not the best

                The first code example just shows where I got the idea for the code in the second example.
                And how I color the rows.

                I just want to know how I can read the information of a cell and, because of the content, write content in a cell of my choice

                For example:
                I want color the row red if in one of the cells of the row stands a 0.
                therefore I want to write "red" in the first cell of the row if that is true.

                I hope you understand what I mean

                I understand if you haven't time to help me.

                JonBJ 1 Reply Last reply
                0
                • M Mogli123

                  sorry my enlish ist not the best

                  The first code example just shows where I got the idea for the code in the second example.
                  And how I color the rows.

                  I just want to know how I can read the information of a cell and, because of the content, write content in a cell of my choice

                  For example:
                  I want color the row red if in one of the cells of the row stands a 0.
                  therefore I want to write "red" in the first cell of the row if that is true.

                  I hope you understand what I mean

                  I understand if you haven't time to help me.

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

                  @Mogli123
                  Very briefly:

                  I want color the row red if in one of the cells of the row stands a 0.
                  therefore I want to write "red" in the first cell of the row if that is true.

                  Do you want to color the row (use role == Qt::BackgroundRole like first example) or do you want to write the string "red" in the first column's cell (use role == Qt::DisplayRole()) like your second example, or both, or what?

                  1 Reply Last reply
                  1
                  • M Offline
                    M Offline
                    Mogli123
                    wrote on last edited by Mogli123
                    #9

                    At first thank you for your answers

                    First I want to write the color in a cell (for example "red")
                    After that I want to color the row with the wantet color like the first example

                    I know that I could color the lines with the desired condition without writing the color in the cell
                    but i would like to separate these two methods if possible

                    JonBJ 1 Reply Last reply
                    0
                    • M Mogli123

                      At first thank you for your answers

                      First I want to write the color in a cell (for example "red")
                      After that I want to color the row with the wantet color like the first example

                      I know that I could color the lines with the desired condition without writing the color in the cell
                      but i would like to separate these two methods if possible

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

                      @Mogli123
                      My literally last scribbled ideas:

                      • You will need your function to have two cases, one for role == Qt::BackgroundRole and another for Qt::DisplayRole(), respectively.

                      • If you have multiple cells in a row, and you want to know if any of them contains something to affect the coloring, you'll need to look at all the cells after the first one, calling sibling() or similar in a loop to look at each one.

                      • I think you'll need to set the Qt::BackgroundRole for each cell (unless there's a way to do it one for a whole row), but set the Qt::DisplayRole() only for column 0.

                      • Do not examine the value of column 0 itself when calculating, as you may recurse infinitely.

                      1 Reply Last reply
                      1
                      • JonBJ JonB

                        @VRonin

                        index.sibling(index.row(), index.column()) is index

                        What does this mean? QModelIndex::sibling() returns some (next?) "sibling" of index, no (err, now I wonder..)? I said the OP that he must check that is valid.

                        QSqlQueryModel::data(index, Qt::DisplayRole);

                        I'm getting lost here in C++ vs the Python I have to use for PyQt/Qt. I thought this would still call his TableCustomise::data() override on the cell specified by index, no? I'm sure when I tried this via PyQt (we can't use the same syntax as C++, and we cannot directly call C++ function, only their PyQt wrappers) it did.... :(

                        VRoninV Offline
                        VRoninV Offline
                        VRonin
                        wrote on last edited by
                        #11

                        @JonB said in get the content from a tableview and change it:

                        What does this mean?

                        QModelIndex QAbstractItemModel::sibling(int row, int column, const QModelIndex &idx) const
                        {
                            return (row == idx.row() && column == idx.column()) ? idx : index(row, column, parent(idx));
                        }
                        

                        so if you pass the same rows and columns as the original index you get back the original index

                        "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

                        1 Reply Last reply
                        2
                        • M Offline
                          M Offline
                          Mogli123
                          wrote on last edited by
                          #12

                          I have changed

                          QString content = index.sibling(index.row(), 0).data(Qt::DisplayRole).toString();
                          

                          to

                           QString content = index.sibling(index.row(), index.column()).data(Qt::EditRole).toString();
                          

                          and it seems that it works
                          is this the right way?

                          my only problem now is that i would separate the to mehods

                          the problem is that they have the same nam
                          but on which place I can change the name that I can separate the methods?

                          sorry for that if this is basic

                          JonBJ 1 Reply Last reply
                          0
                          • M Mogli123

                            I have changed

                            QString content = index.sibling(index.row(), 0).data(Qt::DisplayRole).toString();
                            

                            to

                             QString content = index.sibling(index.row(), index.column()).data(Qt::EditRole).toString();
                            

                            and it seems that it works
                            is this the right way?

                            my only problem now is that i would separate the to mehods

                            the problem is that they have the same nam
                            but on which place I can change the name that I can separate the methods?

                            sorry for that if this is basic

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

                            @Mogli123
                            You cannot "separate the methods", per se.

                            The way Qt works is that its infrastructure always calls QSqlQueryModel::data(index, role) (and thus your TableCustomise::data() override) for different attributes/effects/results, passing in varying values for role accordingly. That's just the way it is, and you cannot alter that.

                            Usually you just write your overload stuff in the one function, using if (role == ...) ... else if (role == ) ... else ... (or similar, you may be able to use a switch statement instead for neatness) for the various cases, and your code is all in that function.

                            If you feel your code is too big, you would have to write your own separate, new functions for each case and just call them in your code, like:

                            QVariant TableCustomise::data(const QModelIndex &index, int role)const
                            {
                                if (role == Qt::DisplayRole())
                                    return displayData(index);
                                else if (role == Qt::backgroundRole())
                                    return backgroundData(index);
                                else
                                    return QSqlQueryModel::data(index, role) ;
                            }
                            
                            QVariant TableCustomise::displayData(const QModelIndex &index )const
                            {
                                return ...;
                            }
                            
                            QVariant TableCustomise::backgroundData(const QModelIndex &index )const
                            {
                                return ...;
                            }
                            
                            1 Reply Last reply
                            3
                            • M Offline
                              M Offline
                              Mogli123
                              wrote on last edited by
                              #14

                              Thank you very much

                              that looks great

                              I will trie it

                              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