Is it possible to use existing `QListWidget` and `QListWidgetItem` style for new `QListView` with custom painted delegate?
-
I am currently working on a plugin for a QT6 application that has theming support. The themes are basically a theme-specific stylesheet that is loaded, which contains styles for various widgets, such as a
QListWidget
andQListWidget::item
.In my plugin, I need to use a
QListView
and aQStyledItemDelegate
derived delegate which paints each item in the list.Is it possible to have my list inherit the basic styles that were set by the theme for a
QListWidget
? Specifically, the item size, background color, corner radius, etc? -
Hi,
You have QStyle that can be used as well as QStyleOptionViewItem. Note that you already get the options in the paintEvent.
-
But where does that QStyle come from? Looking at the CSS/theme files, there are entries for
QListWidget
andQListWidget:item
, but nothing for aQListView/QListView:item
. Is there any way to extract the styles that would be applied to aQListWidget/item
and apply them to my customQListView
? (or am I thinking about this the wrong way?) -
But where does that QStyle come from? Looking at the CSS/theme files, there are entries for
QListWidget
andQListWidget:item
, but nothing for aQListView/QListView:item
. Is there any way to extract the styles that would be applied to aQListWidget/item
and apply them to my customQListView
? (or am I thinking about this the wrong way?)@MarkLT1 said in Is it possible to use existing `QListWidget` and `QListWidgetItem` style for new `QListView` with custom painted delegate?:
Is there any way to extract the styles that would be applied to a QListWidget/item and apply them to my custom QListView?
(or am I thinking about this the wrong way?)Kinda.
QStyle
is notQStyleSheet
andQStyleSheet
is not (exactly) the same as CSS
(some things work the same and it supports many CSS features, but still, as the name tells,QStyleSheet
is more of a Qt "stylesheet" than "real" CSS)See
QStyle
documentation for more details.
You need to include theQStyleOption...
in your custom widget'spaintEvent
when you plan to use stylesheets, or else you will not haveQStyleSheet
support.
(see this recent topic)As @SGaist said, you can implement your custom widget, using the "native" style in your
paintEvent
and paint some more things on top of it, if your wish.PS:
If you consider writing your own
QStyle
, note:Warning: Qt style sheets are currently not supported for custom QStyle subclasses. We plan to address this in some future release.
-
Thank you both for the feedback/ideas. I suspect I may be doing stuff completely wrong here from a design point of view, which might be why styling doesn't seem to work. @Pl45m4, you are mentioning widgets and styling widgets, and I'm a bit lost as to which widgets I am trying to stylize.
I have list of items that I want to display that is 1k+ items. The list needs a custom widget, as each item has 3 buttons that perform actions on that item. Something like this:
I first tried using a normal
QListWidget
where each gets asetItemWidget
with a custom widget that contains the item label and buttons. This worked great, and inherited all of the styling from the theme/style that is loaded into the app (e.g.- a nice blue background for hover, darker blue for select, a nice rounded corner for the selected/hovered list items, etc..). However once the number of items in the list exceeded a couple hundred, it became extremely slow to load.Thus I moved to using a
QListView
and a customQStyledItemDelegate
to draw the items. ThisQStyledItemDelegate
implements apaint
method, and draws out a text box, button boxes, etc:void QuickAccessSourceDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { const auto model = static_cast<const QuickAccessSourceModel*>(index.model()); auto item = model->item(index.row()); std::string mode = obs_frontend_is_theme_dark() ? "theme:Dark/" : "theme:Light/"; QString text = item->getName().c_str(); QRect rect = option.rect; if(option.state & QStyle::State_Selected) painter->fillRect(option.rect, option.palette.highlight()); if (option.state & QStyle::State_MouseOver) painter->fillRect(option.rect, option.palette.accent()); QRect textRect(rect); textRect.setWidth(rect.width() - 107); textRect.setHeight(30); textRect.setX(32); painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, text); int loc = START_LOC; int inc = INC; if (_dock->ShowScenes()) { QRect ParentScenesButtonRect(rect); ParentScenesButtonRect.setX(rect.width() - loc); ParentScenesButtonRect.setHeight(30); ParentScenesButtonRect.setWidth(30); QStyleOptionButton parentScenesButton; parentScenesButton.rect = ParentScenesButtonRect; QIcon scenesIcon; std::string scenesIconPath = mode + "sources/scene.svg"; scenesIcon.addFile(scenesIconPath.c_str(), QSize(), QIcon::Normal, QIcon::Off); parentScenesButton.icon = scenesIcon; parentScenesButton.iconSize = QSize(16, 16); parentScenesButton.state = _filtersState | QStyle::State_Enabled; style->drawControl(QStyle::CE_PushButtonLabel, &parentScenesButton, painter, widget); loc += inc; } if (_dock->ShowFilters()) { // Same as ShowScenes Above loc += inc; } if (_dock->ShowProperties() && item->hasProperties()) { // Same as ShowScenes Above loc += inc; } textRect.setWidth(rect.width() - (loc + 2)); }
It then has a an
editorEvent
implemented that takes care of the button presses.- Is the fact that I am using primitives in a paint function part of why theming wont work?
- Is there a way to use standard widgets in my
StyledItemDelegate
rather than using all primitives in a paint function? - Is there a better way to do this?
One thing I've noticed- the
fillRect
I am calling to fill the background rectangle if hovered/selected works, however the color it is grabbing seems to be the default QT6 colors, not the stylesheet colors that are loaded for aQListWidget:item
in the app.