Good morning
I’m trying to set dark mode with wx on windows
But the dark mode does not apply to all items
Is there something I forgot to do?
hello, which instructions did you use?
Marco
This is the example
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, title):
super(MyFrame, self).__init__(parent, title=title, size=(400, 300))
self.panel = wx.Panel(self)
# Set dark theme colors
dark_bg_color = "#252525" # Dark background color
dark_fg_color = "#FFFFFF" # Dark foreground color
# Set dark theme for the frame and panel
self.SetBackgroundColour(dark_bg_color)
self.panel.SetBackgroundColour(dark_bg_color)
# Creating a read-only multi-line edit box
self.text_ctrl = wx.TextCtrl(self.panel, style=wx.TE_MULTILINE | wx.TE_READONLY)
# Creating buttons
self.button1 = wx.Button(self.panel, label='Button 1')
self.button2 = wx.Button(self.panel, label='Button 2')
self.button3 = wx.Button(self.panel, label='Button 3')
self.button4 = wx.Button(self.panel, label='Button 4')
# Creating an edit box for path and browse button
self.path_text_ctrl = wx.TextCtrl(self.panel)
self.browse_button = wx.Button(self.panel, label='Browse')
# Setting up the layout using a sizer
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.text_ctrl, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)
button_sizer = wx.BoxSizer(wx.HORIZONTAL)
button_sizer.Add(self.button1, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
button_sizer.Add(self.button2, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
button_sizer.Add(self.button3, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
button_sizer.Add(self.button4, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
path_sizer = wx.BoxSizer(wx.HORIZONTAL)
path_sizer.Add(self.path_text_ctrl, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
path_sizer.Add(self.browse_button, flag=wx.ALL, border=5)
sizer.Add(button_sizer, flag=wx.EXPAND)
sizer.Add(path_sizer, flag=wx.EXPAND | wx.ALL, border=10)
self.panel.SetSizer(sizer)
# Binding events
self.browse_button.Bind(wx.EVT_BUTTON, self.on_browse)
def on_browse(self, event):
dialog = wx.FileDialog(self, "Choose a file", style=wx.FD_OPEN)
if dialog.ShowModal() == wx.ID_OK:
path = dialog.GetPath()
self.path_text_ctrl.SetValue(path)
dialog.Destroy()
if __name__ == '__main__':
app = wx.App()
frame = MyFrame(None, "Window with wxPython")
frame.Show()
app.MainLoop()
Are there solutions to use dark mode with wxpython?
You should check on wxwidgets mailing lists about this. There was discussion in the last months about accessing OS API for dark mode. Using setbackground/foreground directly in wxpython code is tedious and probably has limitations. I recently found win32mica (only win11): it states to work also with wxpython but haven’t tried yet. If someone has experience with this or other approaches please share
Marco
Looks like MSWEnableDarkMode is in wxWindows 3.3.0, I can’t confirm it works… just looking at github
as far I know we’re on wxWidgets’ 3.2.0 release tag
I am using wxpython==4.1.1 version
I don’t know if dark mode is disabled
And how can something like this be disabled at a time when all programs and systems tend to support dark mode
I would love to see something more general about support of normal vs. dark mode, but what I have found is that if I set colors directly, I may run into problems where widgets or text become invisible in one mode or the other, because foregrounds and backgrounds have the same or close colors. If instead, I use something like this:
<widget>.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
and use the colors defined here: wx.SystemColour — wxPython Phoenix 4.2.1 documentation then this works much better. Further, at least on MacOS, if the system transitions between dark/light my windows all change nicely.
@MesterPerfect - I’m not clear what you are trying to do. Are you trying to make your wxPython application respond to changing the operating system to a dark theme? Or are you not changing the OS theme, but just trying to make your application simulate a dark theme on its own?
I only run on linux and, if I change the desktop to use a dark theme, nearly all wxPython controls display in the correct dark theme colours without my having to make any code changes. The only exceptions I have noticed are controls for which I have already explicit set specific colours, plus the StyledTextCtrl.
I’m trying to get my app to emulate a dark theme on its own
As for the mode switching that happens to you on Linux, it doesn’t happen on Windows
I don’t think this will work but I will try
@RichardT I’m trying to get my app to emulate a dark theme on its own
As for the mode switching that happens to you on Linux, it doesn’t happen on Windows
Thanks for the clarification. As far as I can see the only option would be to explicitly set the colours for all the controls. Perhaps you could call GetChildren()
recursively. However, I have come across some controls for which GetChildren()
returns an empty list, so it won’t work in all cases.
I modified the code you posted earlier:
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, title):
super(MyFrame, self).__init__(parent, title=title, size=(400, 300))
self.panel = wx.Panel(self)
# Set dark theme colors
self.dark_bg_color = "#252525" # Dark background color
self.dark_fg_color = "#FFFFFF" # Dark foreground color
# Set dark theme for the frame and panel
# self.SetBackgroundColour(dark_bg_color)
# self.panel.SetBackgroundColour(dark_bg_color)
# Creating a read-only multi-line edit box
self.text_ctrl = wx.TextCtrl(self.panel, style=wx.TE_MULTILINE | wx.TE_READONLY)
# Creating buttons
self.button1 = wx.Button(self.panel, label='Button 1')
self.button2 = wx.Button(self.panel, label='Button 2')
self.button3 = wx.Button(self.panel, label='Button 3')
self.button4 = wx.Button(self.panel, label='Button 4')
# Creating an edit box for path and browse button
self.path_text_ctrl = wx.TextCtrl(self.panel)
self.browse_button = wx.Button(self.panel, label='Browse')
# Setting up the layout using a sizer
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.text_ctrl, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)
button_sizer = wx.BoxSizer(wx.HORIZONTAL)
button_sizer.Add(self.button1, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
button_sizer.Add(self.button2, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
button_sizer.Add(self.button3, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
button_sizer.Add(self.button4, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
path_sizer = wx.BoxSizer(wx.HORIZONTAL)
path_sizer.Add(self.path_text_ctrl, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
path_sizer.Add(self.browse_button, flag=wx.ALL, border=5)
sizer.Add(button_sizer, flag=wx.EXPAND)
sizer.Add(path_sizer, flag=wx.EXPAND | wx.ALL, border=10)
self.panel.SetSizer(sizer)
self.set_dark_mode(self)
# Binding events
self.browse_button.Bind(wx.EVT_BUTTON, self.on_browse)
def set_dark_mode(self, control):
for child in control.GetChildren():
child.SetForegroundColour(self.dark_fg_color)
child.SetBackgroundColour(self.dark_bg_color)
self.set_dark_mode(child)
def on_browse(self, event):
dialog = wx.FileDialog(self, "Choose a file", style=wx.FD_OPEN)
if dialog.ShowModal() == wx.ID_OK:
path = dialog.GetPath()
self.path_text_ctrl.SetValue(path)
dialog.Destroy()
if __name__ == '__main__':
app = wx.App()
frame = MyFrame(None, "Window with wxPython")
frame.Show()
app.MainLoop()
When I ran it using Python 3.10.6 + wxPython 4.2.1 gtk3 (phoenix) wxWidgets 3.2.2.1 on Linux Mint 21.1, I got the following display:
I don’t know if it would work the same on Windows. Also, this example only contains a few simple controls, more complex controls are unlikely to be affected. In addition when you click the ‘Browse’ button it displays a file selection dialog whose colours won’t be affected.
I was afraid of that. Things like scrollbars and other sub-components (like the pop-up menu of a combobox) won’t be accessible to GetChildren()
- I’m not sure that it’s possible to access them at all from wxPython?
It’s really annoying, I’m starting to get tired of this library and I’m thinking of moving to PyQt
If you google MSWEnableDarkMode, you can see the current progress or look here
Or here
Since I’m running embedded, I have a bit more control, but it’s not perfect, menus aren’t themed
I did a bunch of theming work in MFC, what a pain, so the guys on the wxWindows team are doing a great job
It wont be long
Blockquote[quote=“wxdan, post:6, topic:36530, full:true”]
Looks like MSWEnableDarkMode is in wxWindows 3.3.0, I can’t confirm it works… just looking at github
as far I know we’re on wxWidgets’ 3.2.0 release tag
[/quote]
Yes, MSWEnableDarkMode
and wxDarkModeSettings
were added in the current 3.3 unstable development branch. The wxPython 4.2.1 release is using the wxWidgets 3.2.2.1 release.
Looks like we’re going to have to wait a long time for the dark mode to be supported well and reliably