Skip to content

Dark mode for Qt6 - #1488

Open
TheForgotten69 wants to merge 110 commits into
Nerogar:masterfrom
TheForgotten69:fix/qt6-windows-issues
Open

Dark mode for Qt6#1488
TheForgotten69 wants to merge 110 commits into
Nerogar:masterfrom
TheForgotten69:fix/qt6-windows-issues

Conversation

@TheForgotten69

@TheForgotten69 TheForgotten69 commented May 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Fix various small issues that occured on Windows:

  • Remove SetProcessDpiAwareness(1) hack that prevented Qt6 from setting its preferred DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 context. I've tested this as I have two monitor and didn't got the transparent issue or the UI re-render on the other screen FYI. -> Already in preview now
  • Replace the forced light-mode workaround with a Windows-scoped apply_theme() that respects the system dark/light
    preference. Linux/macOS keep Qt's native theming untouched.
  • Add theme.py which applies the existing base stylesheet on all platforms and, on Windows only, layers QSS overrides
    (QTabWidget::pane / QTabBar contrast fixes + an adaptive progressbar) plus a white text-box fix for light mode — since
    Qt's dark mode renders tabs with no contrast on Windows.

The important gist is that the preferred mode is now respected and both light and dark are usable.

Screenshot 2026-05-30 204634 Screenshot 2026-05-30 204639

Test plan

  • pre-commit run --all-files passes
  • Launched the affected UI or script and exercised the change
  • Tested with at least one real preset / config when relevant (note which: Change is purely UI/Visual so no need for such test here)

AI assistance

  • AI-assisted — I have read every line in this diff and can defend each change

Koratahiu and others added 30 commits December 30, 2025 17:04
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… VideoToolUI

Removes abstract _create_browse_dir_button/_create_browse_file_button from
BaseVideoToolUIView and uses the combined path_entry component instead, fixing
widget alignment issues. Adds allow_video_files flag to path_entry.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…IView

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…UIView

Now handled by path_entry in the base class.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…files)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Base view concrete methods were accessing self.controller, self.ui_state,
and toolkit-specific action methods that were only set by CTK subclass
__init__ after the base __init__ call, with no enforcement in the base.

- BaseTrainUIView: add controller/ui_state as constructor params; fix
  sync_cloud_secrets to use controller.train_config; add @AbstractMethod
  for export_training, generate_debug_package, open_profiling_tool
- CtkTrainUIView: reorder __init__ to create deps before base init call;
  replace self.train_config with self.controller.train_config
- BaseCloudTabView: add controller as constructor param
- CtkCloudTabView: pass controller to base __init__, drop redundant assignment
- BaseCaptionUIView: add ABC + @AbstractMethod for 6 action callbacks
- BaseConceptTabView: remove concrete _update_filters() (accessed CTK vars);
  add ConceptConfig import; add concept: ConceptConfig param to
  BaseConceptWidgetView.__init__
- CtkConceptTabView: implement _update_filters(); pass concept to base init
- BaseConceptWindowView: initialize bucket_ax/text_color/canvas to None
- BaseTrainingTabView: replace callbacks dict with 6 @AbstractMethod
  declarations; restore_optimizer_config(variable: str) matches controller
- CtkTrainingTabView: implement all 6 abstract methods directly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The ctypes DPI awareness call is toolkit-specific (fixes CTK transparency
on Windows monitor changes). It already exists in CtkTrainUIView.py and
has no place in the toolkit-agnostic controller.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- PySide6TrainUIView: create train_config/ui_state/controller before base
  init so they can be passed as constructor params; replace self.train_config
  with self.controller.train_config throughout
- PySide6CloudTabView: pass controller to BaseCloudTabView.__init__;
  remove now-redundant self.controller assignment
- PySide6ConceptTabView: implement _update_filters() (removed from base);
  pass concept to BaseConceptWidgetView.__init__
- PySide6TrainingTabView: remove callbacks dict; call build() without it;
  implement 6 abstract methods with logic inlined from private helpers;
  remove now-unused private helper methods

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
search_var/filter_var/show_disabled_var were stored in the base but never
used there after _update_filters() was removed. Subclasses manage them.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…abView

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Qt's dark mode support on Windows is broken (tabs render with no
contrast). apply_theme() applies explicit palette and QSS fixes on
Windows only, using palette() references so it adapts to the system
light/dark preference. Linux/macOS are left to Qt's native handling.

Replaces the previous force-light-mode workaround in train_ui_qt.py.
@TheForgotten69
TheForgotten69 force-pushed the fix/qt6-windows-issues branch from 55b7283 to 81dfba6 Compare June 5, 2026 20:28
@TheForgotten69

Copy link
Copy Markdown
Contributor Author

dark mode is scoped only on window, no custom styles either as the hardcoded white theme is handled

@dxqb

dxqb commented Jun 7, 2026

Copy link
Copy Markdown
Collaborator

thanks! will mark this waiting and come back to it when the Qt branch has merged

@dxqb dxqb added the waiting waiting for something / cannot fix currently label Jun 7, 2026
@dxqb dxqb changed the title Fix Qt6 Windows dark mode rendering and DPI warning Dark mode for Qt6 Jun 13, 2026
@dxqb
dxqb force-pushed the preview branch 2 times, most recently from ce63c57 to 3c96784 Compare June 19, 2026 17:00
@dxqb
dxqb changed the base branch from preview to merge July 5, 2026 09:29
@dxqb dxqb removed the waiting waiting for something / cannot fix currently label Jul 5, 2026
@TheForgotten69

Copy link
Copy Markdown
Contributor Author

I saw that Qt is merged in main, any point in me rebasing @dxqb ?
Changes were minimal, scoped only to windows and can be removed down the line

@dxqb

dxqb commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator

please coordinate this #1593

@Zueuk

Zueuk commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

@TheForgotten69 what was the Windows problem you were fixing here? Qt Fusion style looks fine on Windows for me in both light and dark modes

@dxqb
dxqb changed the base branch from merge to master July 12, 2026 09:05
@TheForgotten69

Copy link
Copy Markdown
Contributor Author

@TheForgotten69 what was the Windows problem you were fixing here? Qt Fusion style looks fine on Windows for me in both light and dark modes

@Zueuk The issue was that light mode was activated by force and didn't respect OS preference. It was also prior to the fusion mode but tbh on a big screen I find fusion way less readable than the default windows 11 that Qt used previously (see attached)
Screenshot 2026-07-22 025802

The goal of this MR is scoped to windows only and just meant respecting OS preference, along with keeping hardcoded light style to linux. Did you got a chance to test it? I see that your PR is based on fusion so you might not have maybe?

@Zueuk

Zueuk commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Hmm, so just enabling Fusion probably fixed all these problems.

In my PR I basically replicated the previous OT look & feel on any platform using the Fusion style (though I was asked to disable most of it for the light theme :) There's a signal to switch themes at runtime too.

@TheForgotten69

Copy link
Copy Markdown
Contributor Author

Hmm, so just enabling Fusion probably fixed all these problems.

In my PR I basically replicated the previous OT look & feel on any platform using the Fusion style (though I was asked to disable most of it for the light theme :) There's a signal to switch themes at runtime too.

No, Fusion is just a style. Separately, on a large screen I find Fusion noticeably less readable than the native windows11 style Qt used before (see my initial screens at the top of this MR).
If you want to replicate the style of OT, what I would suggest is:

  1. I rebase my MR so it respects OS preference and use windows11 theme with minimal changes
  2. Your MR base itself on this and you add any features/styling you feel necessary. So we have essentially the best of both worlds on the more modern theme rather than Fusion which is quite old atm

Does that sound good to you @Zueuk ? That way we get to use the newer and more readable theme along with all your fixes and theming :)

@Zueuk

Zueuk commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Fusion is a custom style that will look the same on any platform, and that's the point because Qt is a cross-platform framework. There is no need for a special treatment on Windows.

@TheForgotten69

Copy link
Copy Markdown
Contributor Author

Fusion is a custom style that will look the same on any platform, and that's the point because Qt is a cross-platform framework. There is no need for a special treatment on Windows.

Going native isn't special-casing Windows, it's removing the special-casing. Forcing Fusion is fighting the platform default for Qt which is windows11 on windows already, which gives you the native, more readable, OS-accessibility-aware result for free.

"Same everywhere" isn't worth it if the alternative provides benefits that I already highlighted, especially given the fact it's purely styling and not ground breaking changes.

@Zueuk

Zueuk commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

IMO it does 🤷‍♂️ quite a normal practice, I actually prefer Fusion in Qt apps.

And yeah, if platform == "Windows": ... literally is a special case, while the same code on all platforms is not.

@TheForgotten69

Copy link
Copy Markdown
Contributor Author

IMO it does 🤷‍♂️ quite a normal practice, I actually prefer Fusion in Qt apps.

Normal practice is using the Qt provided default for each OS, which is exactly why windows11 style exists. Fusion style vs native style is taste though, you could add a style toggle next to your theme toggle, like Mod Organizer (also Qt) does in its settings.

And yeah, if platform == "Windows": ... literally is a special case, while the same code on all platforms is not.

I hadn't updated the MR yet since I wanted to discuss first, but as shown in my earlier comment the testing was scoped to Windows with the intention to be removed down the line.
To me, it sounds like we're aligned on using your work for styling. Native will always beat one size fits all on its own platform, which is why Qt ships windows11 in the first place.

@Zueuk

Zueuk commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Actually Qt's "native" style isn't really native - it is faked, all controls are painted by Qt anyway :) such modern GUI development 🤷‍♂️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants