Skip to content

Conversation

LangQi99
Copy link
Contributor

@LangQi99 LangQi99 commented Sep 16, 2025

PR summary

Addresses issue #27590

I noticed in a screenshot from another PR that out of the six backends displayed, only the Qt5Agg icon fails to adapt to dark mode. It remains black and blends in with the background, making it difficult to distinguish.

Old behavior
image

New behavior
image

Old behavior
image

New behavior
image

PR checklist

@LangQi99 LangQi99 marked this pull request as ready for review September 16, 2025 03:03
@LangQi99 LangQi99 marked this pull request as draft September 16, 2025 04:25
@LangQi99 LangQi99 changed the title fix: Qt5Agg support darkmode icon fix: Qt5Agg support darkmode icon by using svg Sep 16, 2025
@LangQi99 LangQi99 marked this pull request as ready for review September 16, 2025 07:52
@timhoffm
Copy link
Member

Not sure, but would using a QIconEngine remove the need for a manual refresh? As far as I read it, the engine could provide the right-sized image on demand (pull principle), instead of explicitly updating on a dpi-change event (push principle).

Comment on lines 740 to 744
def _render_svg(self, svg_path, pixmap, size, dpr):
"""Render SVG content to pixmap."""
QSvgRenderer = qt_compat.get_qsvg_renderer()
if QSvgRenderer is None:
return QtGui.QPixmap()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find the logic not quite clean. You pass pixmap and sometimes return that pixmap with something rendered into, and sometimes you return a different pixmap. I'd rather have that we either only draw into the pixmap (and then do not need to return anything, or that we change to _create_pixmap_from_* and not pass a pixmap in.

Comment on lines 712 to 713
# Get the current device pixel ratio
dpr = (self.toolbar.devicePixelRatioF() or 1) if self.toolbar else 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idea for further simplification:

move this into a private function _devicePixelRatio().

Then ...

Comment on lines 718 to 726
return self._create_pixmap_from_svg(svg_path, size, dpr)
else:
large_path = self.image_path.with_name(self.image_path.stem + '_large.png')
path = large_path if large_path.exists() else self.image_path
scaled_size = QtCore.QSize(
int(size.width() * dpr),
int(size.height() * dpr)
)
return self._create_pixmap_from_png(path, scaled_size, dpr)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interpret size as logical display size for the scope of this function and hide the calculation of the physical size fully inside the _create_pixmap_from_* functions, using self._devicePixelRatio() in there.

This reduces here to

Suggested change
return self._create_pixmap_from_svg(svg_path, size, dpr)
else:
large_path = self.image_path.with_name(self.image_path.stem + '_large.png')
path = large_path if large_path.exists() else self.image_path
scaled_size = QtCore.QSize(
int(size.width() * dpr),
int(size.height() * dpr)
)
return self._create_pixmap_from_png(path, scaled_size, dpr)
return self._create_pixmap_from_svg(svg_path, size)
else:
return self._create_pixmap_from_png(self.image_path, size)

All the type-dependent implementation details (dpi handling, using a possibly available _large PNG image) are then hidden in the respective function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your patient feedback and guidance. I've really learned a lot from it.💡

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LangQi99 thanks as well for the patience to go through the sequence of review cycles! We try to keep them low, but in this case, the proper solution only revealed itself step-by-step. But maybe seeing the evolution of thoughts is also instructive 😃.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants