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. Set color to tableview to certain row
QtWS25 Last Chance

Set color to tableview to certain row

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 4 Posters 297 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.
  • Thank YouT Offline
    Thank YouT Offline
    Thank You
    wrote on last edited by
    #1

    912281d4-b703-44b4-b566-3961d2b8e295-image.png
    Here I want to show row "GREEN" to row with important false
    and "BLUE" to row with important true

    It is fetched from database using mysql query

        tb= QSqlDatabase::addDatabase("QMYSQL","full-settings-table");
        tb.setDatabaseName("message");
        tb.setPort(3306);
        tb.setHostName("localhost");
        tb.setUserName("root");
        tb.setPassword("");
      QString command = "select * from messages;";
        {
    
      
        if(tb.open()){
            QSqlQueryModel *model = new QSqlQueryModel();
               QSqlQuery *query = new QSqlQuery(tb);
               query->prepare(command);
            if(query->exec()){
                model->setQuery(*query);
    
                ui->data->setModel(model);
    
            }else{
     //   QMessageBox::warning(this,"dataaaaaaa","not\n"+query->lastError().text());
            }
    
        }else{
    //not connected
        }
    
        }
            QSqlDatabase::removeDatabase("report"); // removing database
    
    

    I have gone through these
    https://forum.qt.io/topic/83984/how-to-set-current-cell-color-in-a-tableview-and-how-to-set-text-centeraligned
    https://forum.qt.io/topic/125874/qtableview-set-background-color-to-some-columns/3

    They all say some kind of different things Like proxy model and delegate.
    But I don't know about this topic.

    So is there simple way to implement this?

    Let's make QT free or It will go forever

    TRUE AND FALSE <3

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

      I am really torn, here there are 2 solutions:
      1)

      class BackgroundBrushDelegate : public QStyledItemDelegate{
          Q_OBJECT
          Q_DISABLE_COPY(BackgroundBrushDelegate)
      public:
          explicit BackgroundBrushDelegate(QObject *parent = nullptr)
              : QStyledItemDelegate(parent)
          {}
          BackgroundBrushDelegate(const QBrush& brush, QObject *parent = nullptr)
              : QStyledItemDelegate(parent)
          {}
      protected:
          void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const override
          {
              QStyledItemDelegate::initStyleOption(option,index);
              if(index.siblingAtColumn(3).data().toBool())
                  option->backgroundBrush = QBrush(Qt::blue);
              else
                  option->backgroundBrush = QBrush(Qt::green);
          }
      };
      

      ui->data->setItemDelegate(new BackgroundBrushDelegate(this));


      class BackgroundBrushProxy : public QIdentityProxyModel{
          Q_OBJECT
          Q_DISABLE_COPY(BackgroundBrushProxy)
      public:
          explicit BackgroundBrushProxy(QObject *parent = nullptr)
              : QIdentityProxyModel(parent)
          {}
          QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override{
              if(role == Qt::BackgroundRole && index.isValid()){
                  if(index.siblingAtColumn(3).data().toBool())
                      return QBrush(Qt::blue);
                  return QBrush(Qt::green)
              }
              return QIdentityProxyModel::data(index,role);
          }
      };
      

      And replace ui->data->setModel(model); with:

      BackgroundBrushProxy *proxy = new BackgroundBrushProxy(this);
      proxy->setSourceModel(model);
      ui->data->setModel(proxy);
      

      The decision on which is better, however, is purely philosophical (is it just user representation so use 1 or is a property of the data and 2 should be used?) and both work. The argument to siblingAtColumn is what determines what column is looked at, you probably want to handle it with a private variable + getter/setter methods or with an enum in real code to avoid it breaking when you change the code later on


      P.S.
      In your code example you are likely leaking the model and there is no reason to allocate the query on the heap. It should be:

       if(tb.open()){
              QSqlQueryModel *model = new QSqlQueryModel(this);
                 QSqlQuery query(tb);
                 query.prepare(command);
              if(query.exec()){
                  model->setQuery(query);
      
                  ui->data->setModel(model);
      

      "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
      3
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #2

        Hi,

        Implement a custom QIdentityProxyModel and return the color you want for the background role of that column based on the value at the index.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        1
        • Thank YouT Offline
          Thank YouT Offline
          Thank You
          wrote on last edited by
          #3

          @SGaist
          I was about to ask this question. I prepared whole question but was still searching for the answer.
          I found this one written by @VRonin (Thank you sir)

          class BackgroundBrushDelegate : public QStyledItemDelegate{
              Q_OBJECT
              Q_PROPERTY(QBrush backgroundBrush READ backgroundBrush WRITE setBackgroundBrush NOTIFY backgroundBrushChanged)
              Q_DISABLE_COPY(BackgroundBrushDelegate)
          public:
              explicit BackgroundBrushDelegate(QObject *parent = nullptr)
                  : QStyledItemDelegate(parent)
              {}
              BackgroundBrushDelegate(const QBrush& brush, QObject *parent = nullptr)
                  : QStyledItemDelegate(parent)
                  , m_backgroundBrush(brush)
              {}
              const QBrush& backgroundBrush() const { return m_backgroundBrush; }
              void setBackgroundBrush(const QBrush& brush)
              {
                  if(m_backgroundBrush==brush)
                      return;
                  m_backgroundBrush=brush;
                  backgroundBrushChanged(m_backgroundBrush);
              }
          signals:
              void backgroundBrushChanged(const QBrush& brush);
          protected:
              void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const override
              {
                  QStyledItemDelegate::initStyleOption(option,index);
                  option->backgroundBrush = m_backgroundBrush;
              }
          private:
              QBrush m_backgroundBrush;
          }
          

          I am using it. But I don't know how it works and other stuffs.

          In addition to @mrjj, QIdentityProxyModel is also a solution.

          In that question also You mentioned it but I don't know both of these.

          After searching about this, I found majority of answers include either https://doc.qt.io/qt-5/qidentityproxymodel.html or Delegate.

          I would be happy to get the answer which looks simple. I am not pro at it. I understand the syntax of upper code but I can't visualize it( I don't know what delegate is and what ProxyModel is 😂😂, I just know sth about model ).

          Thank You 😊☺

          Let's make QT free or It will go forever

          TRUE AND FALSE <3

          1 Reply Last reply
          0
          • JoeCFDJ Offline
            JoeCFDJ Offline
            JoeCFD
            wrote on last edited by
            #4

            Assign background color to each item of that row.

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #5

              Did you already went through the Model View introduction in Qt's documentation ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              Thank YouT 1 Reply Last reply
              0
              • SGaistS SGaist

                Did you already went through the Model View introduction in Qt's documentation ?

                Thank YouT Offline
                Thank YouT Offline
                Thank You
                wrote on last edited by
                #6

                @SGaist I knew something about this before.
                I will read it now
                Thanks

                Let's make QT free or It will go forever

                TRUE AND FALSE <3

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

                  I am really torn, here there are 2 solutions:
                  1)

                  class BackgroundBrushDelegate : public QStyledItemDelegate{
                      Q_OBJECT
                      Q_DISABLE_COPY(BackgroundBrushDelegate)
                  public:
                      explicit BackgroundBrushDelegate(QObject *parent = nullptr)
                          : QStyledItemDelegate(parent)
                      {}
                      BackgroundBrushDelegate(const QBrush& brush, QObject *parent = nullptr)
                          : QStyledItemDelegate(parent)
                      {}
                  protected:
                      void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const override
                      {
                          QStyledItemDelegate::initStyleOption(option,index);
                          if(index.siblingAtColumn(3).data().toBool())
                              option->backgroundBrush = QBrush(Qt::blue);
                          else
                              option->backgroundBrush = QBrush(Qt::green);
                      }
                  };
                  

                  ui->data->setItemDelegate(new BackgroundBrushDelegate(this));


                  class BackgroundBrushProxy : public QIdentityProxyModel{
                      Q_OBJECT
                      Q_DISABLE_COPY(BackgroundBrushProxy)
                  public:
                      explicit BackgroundBrushProxy(QObject *parent = nullptr)
                          : QIdentityProxyModel(parent)
                      {}
                      QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override{
                          if(role == Qt::BackgroundRole && index.isValid()){
                              if(index.siblingAtColumn(3).data().toBool())
                                  return QBrush(Qt::blue);
                              return QBrush(Qt::green)
                          }
                          return QIdentityProxyModel::data(index,role);
                      }
                  };
                  

                  And replace ui->data->setModel(model); with:

                  BackgroundBrushProxy *proxy = new BackgroundBrushProxy(this);
                  proxy->setSourceModel(model);
                  ui->data->setModel(proxy);
                  

                  The decision on which is better, however, is purely philosophical (is it just user representation so use 1 or is a property of the data and 2 should be used?) and both work. The argument to siblingAtColumn is what determines what column is looked at, you probably want to handle it with a private variable + getter/setter methods or with an enum in real code to avoid it breaking when you change the code later on


                  P.S.
                  In your code example you are likely leaking the model and there is no reason to allocate the query on the heap. It should be:

                   if(tb.open()){
                          QSqlQueryModel *model = new QSqlQueryModel(this);
                             QSqlQuery query(tb);
                             query.prepare(command);
                          if(query.exec()){
                              model->setQuery(query);
                  
                              ui->data->setModel(model);
                  

                  "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
                  3

                  • Login

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