Enhance the appearance of QTreeView items using a customized display delegate and CSS

In my QTreeView, I have a custom delegate set up for one of the columns to display a colored progress bar. The appearance of the progress bar depends on the content and I used the color information from option.palette to mimic the default delegate behavior.

class ProgressBarDelegate : public QStyledItemDelegate
{
public:
    ProgressBarDelegate(QObject *parent = 0) {}
    ~ProgressBarDelegate() {}
    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        // QStyledItemDelegate::paint(painter, option, index); // default implementation

        painter->save();

        // progressbar construction and drawing

        painter->restore();
    }
};

Now, I want to highlight a row when hovering over it with the mouse. I added custom CSS to the tree view:

ui->treeView->setStyleSheet("QTreeView::item:hover{background-color:#D0E0F0;}");

The hover highlighting works fine, but unfortunately, my custom delegate does not take into account the CSS settings:

https://i.stack.imgur.com/1BzkN.png

(The dark blue line represents the selected item, while the light blue line is the CSS hover-highlighted row)

If I enable the default implementation, the CSS setting affects my delegate, but it messes up the visual presentation:

https://i.stack.imgur.com/TNR9f.png

The main question is:

  • Is there a way to access the overridden CSS settings data within the delegate? It seems like option.palette doesn't provide this information.

I tried to read the QTreeView property as suggested here:

qDebug() << treeView()->property("background");

but the console output shows QVariant(Invalid)

I also attempted to look at the Qt source code for the drawControl() and drawPrimitive() methods used in the default delegate implementation, but I couldn't find any references to the CSS overrides, only widget palette connections.

Answer №1

Upon reviewing the source code, it became apparent that accessing CSS data from within the delegate by default is not possible as the CSS parsing and calculations are managed by a private QStyleSheetStyle object that applications do not have direct access to. This object simply adjusts the option.palette fields for use in drawing routines.

Nevertheless, there is a method to compel the delegate to render certain elements with desired settings without having to manually parse the option.palette fields by utilizing the style's drawPrimitive() method:

// rendering background with preferred colors:
option.widget->style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter);

This approach will display the background with the appropriate settings:

https://i.stack.imgur.com/ggXSs.png

I suspect that there might be a similar technique to apply the CSS-modified setting, something along the lines of:

option.widget->style()->proxy()->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter);

However, my lack of comprehension regarding Qt's style framework has hindered my ability to locate it so far.

Answer №2

When implementing the component's visual representation within the paint method, you have the opportunity to incorporate a "hover" effect.

An example of how this can be achieved is shown below:

// check for hover state
QStyleOptionViewItemV4 styleOption(option);
bool mouseOver = (styleOption.state & QStyle::State_MouseOver);
// apply hover effect     
if(mouseOver) {
...
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The media query for mobile is not functioning properly

Hello, I have a page with MVC that includes CSS for iPad and mobile devices. The media query for iPad (@media only screen and (min-device-width: 768px) and (max-device-width: 1024px)) works perfectly, but I am struggling to get the media query for mobile ...

Using JavaScript to create CSS animations triggered on hover

Looking for a CSS Animation that will play forward once when the mouse enters a specific div, and then play in reverse when the mouse leaves. Check out my JsFiddle here. The div with the class ".item" should trigger the mouse enter event. The animation co ...

What is the most efficient way to define the font properties for all H1-H6 headings in a single declaration

Is there a way to set all font properties for H1-H6 headings in one CSS declaration? CSSLint.net is flagging multiple definitions of heading styles as an issue. I currently have specific styles for each heading level: h1 { font-size: 1.8em; margin-top: ...

How can I make a CSS transition activate only on width increases, not decreases?

My element's width changes under different conditions, and I've implemented CSS with a transition for the width: .element-class { transition: width 500ms ease 0ms; } However, I only want the transition to occur when the width is decreasing. ...

css based on the current time in the United States

I have a working code that currently reads the user's computer time, but I specifically need to get the hours from the USA regardless of the user's location. The CSS should be applied based on USA time. <script type="text/javascript"> dat ...

Adjusting the size of a Google map based on the size of the browser

Currently, I am working on implementing Google Maps API v3. The map is displaying perfectly on my page, but the issue arises when I resize the browser. Upon resizing, the map reverts to its original size as it was when the page initially loaded. This is t ...

Custom cellRenderer prevents Ag Grid's autoHeight and wrapText features from functioning properly

I've been attempting to adjust the formatting of a long cell value by wrapping the text. According to the documentation, setting autoHeight=true and wrapText=true works fine without any cellRenderer components. However, when using a cellRendererFramew ...

Tips for altering the background of a video on Vonage

Hello everyone, Currently, I am incorporating the Vonage API for video calling into my project. I would like to tweak the video background - does anyone have any ideas on how to accomplish this? I eagerly await your responses! Thank you in advance! ...

Steer clear of posting additional content that might bump the existing content further up

How can I keep the search bar centered on the screen, even when content is added below it? Here's a screenshot illustrating the issue: https://i.stack.imgur.com/7pQ1q.png The text in the image is causing the search bar to move up, but I want the sea ...

What could be causing the HTML and CSS to not show the background image?

Hey, I'm new to html and css and I'm having trouble getting a background image to show up on my website. All I see is "first website" in the corner but the image isn't displaying. Here's the code I have: * { margin: 0; padding: 0 ...

Creating multi-level nested lists with numbering using HTML and CSS

Is there a way to create a unique numbering format using only HTML and CSS lists (<ul> or <ol>)? 1. Item A 2. Item B 3. Item C 3.1. Subitem C.1 3.2. Subitem C.2 3.3. Subitem C.3 4. Item D 4.1. Subitem D.1 4.1.1 Sub-subi ...

Adjusting the width of the container <div> will automatically resize the inner <div> to match

I have a main container element. .wrapper{ border:1px solid blue; position:relative; top:20%; left:30%; height: 300px; width: 350px; } When I adjust the width of the parent container, the child box does not reposition itself accor ...

Is it possible to modify the concealed global attribute using CSS?

Imagine this scenario: <div hidden>blah blah blah</div> If I hide the <div> element like that, can CSS be used to make it visible again? Alternatively, is there an HTML-only method to hide a <div> that can later be reversed with ...

What could be causing my hover effect to function exclusively on Chromium-based browsers and not on Firefox?

Could use some help with this code snippet .podmenu { display: flex; flex-direction: column; list-style: none; width: 10rem; margin-left: 3rem; margin-bottom: 60px; } .verze { list-style: none; flex-direction: column; ...

ways to set a background color for a textarea element using bootstrap

How can I add a background color to my text area field in Bootstrap? <div class="form-group"> <div class="col-xs-12"> <textarea class="form-control" id="exampleTextarea" rows="6" placeholder="Message" style="background-color: #f ...

Dynamically include new events

Here is the code snippet I have in a JS file: $(".dropmenu").on("click", function(event){ event.preventDefault(); $(this).parent().find("ul").slideToggle(); }); On my webpage, I'm using the following code: var append="<ul> ...

Turn off the ability for items in Isotope to be set to an absolute

Currently, I am customizing my portfolio and looking to implement my own method for positioning the portfolio items. The Isotope library typically uses absolute positioning with left and top properties to position portfolio elements. Even after trying to o ...

"Troubleshooting the lack of background image display in Next.js when using

Can anyone help me figure out why my background image disappears when I add a linear gradient? It shows up fine without the gradient, but as soon as I include it, the image vanishes. <div className="hero" style={{background: "linear-grad ...

Using CSS and JavaScript to hide a div element

In my one-page website, I have a fixed side navigation bar within a div that is initially hidden using the display:none property. Is there a way to make this side nav appear when the user scrolls to a specific section of the page, like when reaching the # ...

Tips on updating the color of the drawer component's background in Material-UI using React

I have been attempting to change the background color of a drawer component in React, but I have only been successful in changing the background behind the drawer or the field with the items. Here is the code I am using: const useStyles = makeStyles({ ...