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 to style QTreeView items by role with CSS ?
QtWS25 Last Chance

How to style QTreeView items by role with CSS ?

Scheduled Pinned Locked Moved Unsolved General and Desktop
qtreeviewcssqtwidgetsstylesmodel-view
9 Posts 3 Posters 10.4k 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.
  • Z Offline
    Z Offline
    Zylann
    wrote on last edited by
    #1

    Hello,
    I have a QTreeView and a custom model in an application which uses a custom CSS stylesheet.
    I want to color some items in my tree view depending on their Qt::ForegroundRole, which returns a non-null color in some specific cases.
    However it seems CSS overrides this and my items don't change color.

    So I wondered if it's possible, like in HTML, to put "CSS classes" on items so I can style them directly in CSS for the special cases my application defines. But I have no clue how to do that, especially with model-view system...

    So I tried QStyledItemDelegate, but again I don't find many examples about how to do this simple thing.
    I have this so far:

    void TextColorDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex &index) const
    {
    	QVariant d = index.data(Qt::ForegroundRole);
    	if (d.type() != QVariant::Color)
    		QStyledItemDelegate::paint(painter, option, index);
    	else
    	{
    		QColor color = d.value<QColor>();
    		QBrush brush = painter->brush();
    		brush.setColor(color);
    		painter->setBrush(brush);
    		QString text = index.data(Qt::DisplayRole).toString();
    		painter->drawText(option.rect, 0, text);
    	}
    }
    

    But all it does is draw a black text with fixed background even when selected, hovered etc.
    Any ideas?

    raven-worxR 1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Do you mean something like described here ?

      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
      0
      • Z Zylann

        Hello,
        I have a QTreeView and a custom model in an application which uses a custom CSS stylesheet.
        I want to color some items in my tree view depending on their Qt::ForegroundRole, which returns a non-null color in some specific cases.
        However it seems CSS overrides this and my items don't change color.

        So I wondered if it's possible, like in HTML, to put "CSS classes" on items so I can style them directly in CSS for the special cases my application defines. But I have no clue how to do that, especially with model-view system...

        So I tried QStyledItemDelegate, but again I don't find many examples about how to do this simple thing.
        I have this so far:

        void TextColorDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex &index) const
        {
        	QVariant d = index.data(Qt::ForegroundRole);
        	if (d.type() != QVariant::Color)
        		QStyledItemDelegate::paint(painter, option, index);
        	else
        	{
        		QColor color = d.value<QColor>();
        		QBrush brush = painter->brush();
        		brush.setColor(color);
        		painter->setBrush(brush);
        		QString text = index.data(Qt::DisplayRole).toString();
        		painter->drawText(option.rect, 0, text);
        	}
        }
        

        But all it does is draw a black text with fixed background even when selected, hovered etc.
        Any ideas?

        raven-worxR Offline
        raven-worxR Offline
        raven-worx
        Moderators
        wrote on last edited by
        #3

        @Zylann
        it's not possible to style items in itemview widgets individually by Qt.

        The only solution is:

        1. add a string property to your tree view
        2. define a simple syntax to define the font colors for your data role values
        3. in the property setter parse the string and set it to the item delegate
        4. subclass initStyleOption() in the delegate (see bleow)
        virtual void MyItemDelegate::initStyleOption(QStyleOptionViewItem * option, const QModelIndex & index) const
        {
             QStyledItemDelegate::initStyleOption(option, index);
        
             if( index.data( MY_ITEM_DATA_ROLE ) == ??? )
             {
                    QPalette::ColorGroup cg = option->state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
                if( cg == QPalette::Normal && !(option->state & QStyle::State_Active) )
                    cg = QPalette::Inactive;
                QColor fontColor = ....;
                option->palette.setColor(cg, option->state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text, fontColor);
             }
        }
        

        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
        If you have a question please use the forum so others can benefit from the solution in the future

        1 Reply Last reply
        0
        • Z Offline
          Z Offline
          Zylann
          wrote on last edited by Zylann
          #4

          @SGaist Yes, theoretically the correct way for the designer would be the ability to wrote something like:

          QTreeView::item:mycustomstate {
             color: #abc;
          }
          

          But at the moment, if I could just get the color to change according to Qt::ForegroundRole, it would be a good start too.

          @raven-worx My model can already return a color when I query data(Qt::ForegroundRole).
          I modified my column delegate so it overrides initStyleOption() like you did, but it has no effect.
          What do you mean by adding a string property to the tree view? Subclass QTreeView? What would be this property for?

          raven-worxR 1 Reply Last reply
          0
          • Z Zylann

            @SGaist Yes, theoretically the correct way for the designer would be the ability to wrote something like:

            QTreeView::item:mycustomstate {
               color: #abc;
            }
            

            But at the moment, if I could just get the color to change according to Qt::ForegroundRole, it would be a good start too.

            @raven-worx My model can already return a color when I query data(Qt::ForegroundRole).
            I modified my column delegate so it overrides initStyleOption() like you did, but it has no effect.
            What do you mean by adding a string property to the tree view? Subclass QTreeView? What would be this property for?

            raven-worxR Offline
            raven-worxR Offline
            raven-worx
            Moderators
            wrote on last edited by
            #5

            @Zylann
            The property was for styling via stylesheets.
            But now you say that the color comes from the model.

            Please show your initStyleOption() implementation.

            --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
            If you have a question please use the forum so others can benefit from the solution in the future

            1 Reply Last reply
            0
            • Z Offline
              Z Offline
              Zylann
              wrote on last edited by
              #6
              void TextColorDelegate::initStyleOption(QStyleOptionViewItem * option, const QModelIndex & index) const
              {
              	QStyledItemDelegate::initStyleOption(option, index);
              
              	QVariant d = index.data(Qt::ForegroundRole);
              	if (d.type() == QVariant::Color)
              	{
              		QColor color = d.value<QColor>();
              
              		QPalette::ColorGroup cg = option->state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
              		if (cg == QPalette::Normal && !(option->state & QStyle::State_Active))
              		{
              			cg = QPalette::Inactive;
              		}
              
              		option->palette.setColor(cg, option->state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text, color);
              	}
              }
              

              I tried again without CSS, I get colors. With CSS, no colors but those from CSS.
              I also realized I was setting the proxy before the model to be set, so now I set it after, but that didn't fixed the problem.

              raven-worxR 1 Reply Last reply
              0
              • Z Zylann
                void TextColorDelegate::initStyleOption(QStyleOptionViewItem * option, const QModelIndex & index) const
                {
                	QStyledItemDelegate::initStyleOption(option, index);
                
                	QVariant d = index.data(Qt::ForegroundRole);
                	if (d.type() == QVariant::Color)
                	{
                		QColor color = d.value<QColor>();
                
                		QPalette::ColorGroup cg = option->state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
                		if (cg == QPalette::Normal && !(option->state & QStyle::State_Active))
                		{
                			cg = QPalette::Inactive;
                		}
                
                		option->palette.setColor(cg, option->state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text, color);
                	}
                }
                

                I tried again without CSS, I get colors. With CSS, no colors but those from CSS.
                I also realized I was setting the proxy before the model to be set, so now I set it after, but that didn't fixed the problem.

                raven-worxR Offline
                raven-worxR Offline
                raven-worx
                Moderators
                wrote on last edited by
                #7

                @Zylann
                are you sure you are successfully passing the condition d.type() == QVariant::Color?
                Because i am almost sure the code works :)
                Also the ForegroundRole would be used already by Qt when you remove the stylesheet.

                --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                If you have a question please use the forum so others can benefit from the solution in the future

                1 Reply Last reply
                0
                • Z Offline
                  Z Offline
                  Zylann
                  wrote on last edited by
                  #8

                  Everything is fine and works when I remove the CSS. But with CSS, I don't get that because the style overrides my code.
                  I even tried to remove the if and hardcode QColor(0,255,0) for every case, with no luck.
                  The only time I got something look "different" is by overriding paint() (see my first post), but it also broke many other things, not only the text color.

                  1 Reply Last reply
                  0
                  • Z Offline
                    Z Offline
                    Zylann
                    wrote on last edited by Zylann
                    #9

                    I finally managed to get custom colors. I gave my QTreeView an object name to be able to write this in CSS:

                    m_treeView->setObjectName("MyTreeView");
                    m_treeView->setStyleSheet("QTreeView#MyTreeView::item {color: none;}");
                    

                    basically now my model controls text color through Qt::ForegroundRole regardless of the application's CSS.
                    I feel like it's the wrong place to put theming, but it works for me at the moment.
                    Well... until we decide to have different themes :-°

                    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