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. How can I change QTableView's color of the area that doesn't have cells on it?
Forum Updated to NodeBB v4.3 + New Features

How can I change QTableView's color of the area that doesn't have cells on it?

Scheduled Pinned Locked Moved General and Desktop
36 Posts 8 Posters 31.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.
  • E Offline
    E Offline
    Edico
    wrote on last edited by
    #23

    I've set the outside area of the cells like that:

    @
    QPalette p = view->palette();
    QColor color = p.color(QPalette::Window);
    p.setColor(QPalette::Base, color);
    view->setPalette(p);
    @

    Then data() in MyProxyModel:

    @
    QVariant MyProxyModel::data(const QModelIndex &index, int role) const
    {
    if (!index.isValid())
    return QVariant::Invalid;

    int row = index.row();
    
    QWidget widget;  // I didn't found a wiser method to obtain the palette colors than creating a QWidget inside the data() method
    QColor alternateColor1 = widget.palette().color(QPalette::AlternateBase);
    QColor alternateColor2 = widget.palette().color(QPalette::Base);
    
    if (role == Qt::BackgroundRole) {
        QBrush rowBackground;
        if (row % 2 == 0)
            rowBackground = QBrush(alternateColor1);
        else if (row % 2 != 0)
            rowBackground = QBrush(alternateColor2);
        return rowBackground;
    }
    return QSortFilterProxyModel::data(index, role);
    

    }
    @

    It does what I wanted.
    Thank you all for the help.

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

      The data method is called very frequently. It is not a good idea to create a widget in this method. Instead, why not just create a pair of getters and setter methods for the colors on the proxy model. Set them once when you create the proxy, and use them in your data method. That will be much more performant.

      1 Reply Last reply
      0
      • E Offline
        E Offline
        Edico
        wrote on last edited by
        #25

        I know it's a little bit outside the subject but, how is much better:
        to have setters like this:

        @
        void MyProxyModel::setAlternateColor1()
        {
        QWidget widget;
        alternateColor1 = widget.palette().color(QPalette::Base);
        }

        void MyProxyModel::setAlternateColor2()
        {
        QWidget widget;
        alternateColor2 = widget.palette().color(QPalette::AlternateBase);
        }
        @

        and data() calling the getters,
        or setting the colors in the constructor like this:

        @
        MyProxyModel::MyProxyModel()
        {
        QWidget widget;
        alternateColor1 = widget.palette().color(QPalette::Base);
        alternateColor2 = widget.palette().color(QPalette::AlternateBase);
        }
        @

        and data using directly QColor alternateColor1 and QColor alternateColor2?

        1 Reply Last reply
        0
        • O Offline
          O Offline
          octal
          wrote on last edited by
          #26

          I think you misunterstood what Andre meant.

          bq. Instead, why not just create a pair of getters and setter methods for the colors on the proxy model.

          A pair of getters/setters would be :

          @
          void MyProxyModel::setAlternateColor1(const QColor &color)
          {
          mAlternateColor1 = color;
          }

          QColor MyProxyModel::alternateColor1() const
          {
          return mAlternateColor1;
          }
          @

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

            Octal:
            Indeed, that's what I meant, and also a getter and a setter for the primary color. You can set them at initialization of your proxy model, which is very likely to be in the constructor of a widget class. Hence, you have cheap access to a widget pointer and the palette there, and you only need that access once.

            1 Reply Last reply
            0
            • E Offline
              E Offline
              Edico
              wrote on last edited by
              #28

              I've created setters and getters. Now I use the proxy like that:

              @
              proxyModel = new MyProxyModel;
              QColor altColor1 = this->palette().color(QPalette::Base);
              QColor altColor2 = this->palette().color(QPalette::AlternateBase);
              proxyModel->setAlternateColor1(altColor1);
              proxyModel->setAlternateColor2(altColor2);
              proxyModel->setSourceModel(model);
              @

              proxyModel's data() method calls the getters.
              Is it better like that?

              Andre, what do you mean with primary color?

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

                As long as you use the colors you set there in your data() method: much better :-)

                One small tip: you will want to give your MyProxyModel object a parent object. Seeing that this proxy is really doing presentation work, I suggest you use the view that it is for as the parent object. Also: a more descriptive name than "MyProxyModel" would probably work better in the long run.

                1 Reply Last reply
                0
                • E Offline
                  E Offline
                  Edico
                  wrote on last edited by
                  #30

                  I've called it PresentationProxyModel :-)
                  Thanks a lot for the help.

                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    alexisdm
                    wrote on last edited by
                    #31

                    The presentation details should normally be handled by the delegates, for example:
                    @class AlternateBackgroundColorDelegate : public QStyledItemDelegate {
                    QColor colors[2];
                    public:
                    AlternateBackgroundColorDelegate(const QColor & color1,
                    const QColor & color2,
                    QObject *parent = 0)
                    : QStyledItemDelegate(parent)
                    {
                    colors[0] = color1;
                    colors[1] = color2;
                    }
                    void initStyleOption(QStyleOptionViewItem *option,
                    const QModelIndex &index) const
                    {
                    QStyledItemDelegate::initStyleOption(option, index);

                        QStyleOptionViewItemV4 *optionV4 =
                                qstyleoption_cast<QStyleOptionViewItemV4*>(option);
                        // If the brush hasn't explicitly been set in the model
                        if (optionV4->backgroundBrush.style() == Qt::NoBrush)
                            optionV4->backgroundBrush = QBrush(colors[index.row()%2]);
                    }
                    

                    };

                    // And you use it like this:
                    tableView->setItemDelegate(
                    new AlternateBackgroundColorDelegate(Qt::blue, Qt::red, tableView));
                    @
                    Or using a different palette for the items and the view:
                    @class ChangePaletteDelegate : public QStyledItemDelegate {
                    QPalette palette;
                    public:
                    ChangePaletteDelegate(const QPalette &palette,
                    QObject *parent = 0)
                    : QStyledItemDelegate(parent), palette(palette)
                    {
                    }
                    void initStyleOption(QStyleOptionViewItem *option,
                    const QModelIndex &index) const
                    {
                    QStyledItemDelegate::initStyleOption(option, index);
                    option.palette = palette;
                    // Edit: the palette isn't used for background color if QPalette::Base is set
                    QStyleOptionViewItemV4 optionV4 =
                    qstyleoption_cast<QStyleOptionViewItemV4
                    >(option);
                    // If the brush has explicitly been set in the model, do nothing
                    if (optionV4->backgroundBrush.style() != Qt::NoBrush)
                    return;

                        if(optionV4->features & oQStyleOptionViewItemV2::Alternate) {
                            optionV4->backgroundBrush = palette.brush(QPalette::AlternateBase);
                        } else {
                            optionV4->backgroundBrush = palette.brush(QPalette::Base);
                        }
                    }
                    

                    };

                    // And you use it like this:
                    QPalette palette = tableView->palette();
                    // Use the original palette here, for the items
                    tableView->setItemDelegate(new ChangePaletteDelegate(palette, tableView));
                    // and change the background for the view
                    palette.setColor(QPalette::Base, Qt::yellow);
                    tableView->setPalette(palette);

                    @

                    Edit Fixed ChangePaletteDelegate.

                    1 Reply Last reply
                    0
                    • E Offline
                      E Offline
                      Edico
                      wrote on last edited by
                      #32

                      alexisdm, l like your way for solving this problem.
                      The palette method doesn't work for me.

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        alexisdm
                        wrote on last edited by
                        #33

                        The palette method only works if you don't use stylesheets at the same time, I think.

                        1 Reply Last reply
                        0
                        • E Offline
                          E Offline
                          Edico
                          wrote on last edited by
                          #34

                          I don't use stylesheets. With ChangePaletteDelegate I have the cells and the outside area of the cells yellow (other color for the alternating row color);

                          1 Reply Last reply
                          0
                          • A Offline
                            A Offline
                            alexisdm
                            wrote on last edited by
                            #35

                            Sorry, I fixed it. It was only working if the QPalette::Base wasn't set explicitly.
                            The alternate row background is painted directly by the view, and not by the delegate as I thought.
                            So in both methods, QStyleOptionViewItemV4::backgroundBrush must be used to change the background color.

                            1 Reply Last reply
                            0
                            • K Offline
                              K Offline
                              krisztiantobias
                              wrote on last edited by
                              #36

                              It's a really old topic, but still usable so: for the empty space below the cells you can use the viewport:

                              tableWidget->viewport()->setStyleSheet("background-color: #888;");
                              
                              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