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:
[image: a92dc886-178c-4cfe-beba-f09eaf66713c.png]
I first tried using a normal QListWidget where each gets a setItemWidget 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 custom QStyledItemDelegate to draw the items. This QStyledItemDelegate implements a paint 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 a QListWidget:item in the app.