Python wxPython: wx.SystemSettings の使い方 – OSの標準色やフォントを取得

Python

PythonとwxPythonでGUIアプリを開発するとき、見た目の「ネイティブ感」は非常に重要です。しかし、こんな失敗はありませんか?

「自作パネルの背景色を #FFFFFF(白)に決め打ちしたら、OSをダークモードに設定しているユーザーの環境で、そこだけ真っ白に浮いてしまった…」 「Windowsに合わせて "MS UI Gothic" を指定したら、macOSやLinuxのユーザーから『フォントが汚い』と報告が来た」

OSの標準的な見た目に合わせようとしても、Windows, macOS, Linuxでは標準色も標準フォントも、さらにはスクロールバーの幅さえも異なります。

この記事では、これらの問題をスマートに解決する wx.SystemSettings クラスに焦点を当てます。wx.SystemSettings を使えば、OSが現在設定している標準の色・フォント・UI部品のサイズを簡単に取得でき、環境に溶け込む「ネイティブ感」あふれるアプリを作れるようになります。

wx.SystemSettings とは?

wx.SystemSettings とは、ひと言でいうと**「OSのUIに関する”設定値”を取得するためのユーティリティクラス」**です。

このクラスの最大のメリットは、色(#FFFFFF)やフォント名("MS UI Gothic")といった値をコードに直接書き込む**「ハードコーディング」を避けられる**点にあります。

OSがライトモードかダークモードか、ユーザーがどのようなフォント設定にしているかに自動で追従できるため、wxPythonアプリの「ネイティブ感」を格段に高めるために不可欠な機能です。

wx.SystemSettings はインスタンスを作成して使うのではなく、wx.SystemSettings.GetColour() のように、クラスから直接静的メソッド (static method) を呼び出して使用します。

wx.SystemSettings の主要なメソッド3選

wx.SystemSettings にはいくつかメソッドがありますが、OSの設定値を取得するために最も重要でよく使われる3つのメソッドを解説します。

  1. GetColour(index): OSの標準色を取得
  2. GetFont(index): OSの標準フォントを取得
  3. GetMetric(index): OSのUI部品のサイズを取得

GetColour(index) – OSの標準色を取得する

GetColour は、OSの現在のテーマ(ライト/ダークモードなど)で定義されている「標準色」を wx.Colour オブジェクトとして取得します。

引数 index には、どの部分の色が欲しいかを示す定数を指定します。wx.SYS_COLOUR_... という名前の定数が多数用意されています。

よく使う色の定数

  • wx.SYS_COLOUR_WINDOW: ウィンドウやパネルの標準的な背景色です。
  • wx.SYS_COLOUR_BTNFACE (または wx.SYS_COLOUR_3DFACE): wx.Button など、立体的なUI部品の標準的な背景色です。
  • wx.SYS_COLOUR_BTNTEXT: ボタン上の標準的なテキスト色です。
  • wx.SYS_COLOUR_LISTBOX: wx.ListBoxwx.TextCtrl などの標準的な背景色です。
  • wx.SYS_COLOUR_HIGHLIGHT: リストなどで項目を選択したとき(ハイライト)の背景色です。
  • wx.SYS_COLOUR_HIGHLIGHTTEXT: 選択された項目のテキスト色です。

コード例: パネルの背景色をOSに合わせる

決め打ちで panel.SetBackgroundColour(wx.Colour(255, 255, 255)) と書く代わりに、以下のように書きます。

import wx

# OS標準のウィンドウ背景色を取得
window_bg_colour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)

# パネル (self.panel) の背景色に設定
self.panel.SetBackgroundColour(window_bg_colour)

こうすることで、OSがダークモードであれば自動的に暗い背景色が取得され、アプリの見た目がOSと調和します。


GetFont(index) – OSの標準フォントを取得する

GetFont は、OSがGUIコンポーネントに使用している「標準フォント」を wx.Font オブジェクトとして取得します。

これにより、「Windowsなら MS UI Gothic、macOSなら Hiragino Kaku Gothic ProN…」といったOSごとの分岐を自分で書く必要がなくなります。

よく使うフォントの定数

  • wx.SYS_DEFAULT_GUI_FONT: (最重要) ボタン、ラベル、テキストボックスなど、GUI部品に使われる標準のフォントです。迷ったらこれを使うのが最も安全です。
  • wx.SYS_SYSTEM_FONT: システムが使用するフォント(やや古い概念で、SYS_DEFAULT_GUI_FONT と同じ場合が多いです)。
  • wx.SYS_ANSI_VAR_FONT: 標準の可変幅フォント。

コード例: ラベルのフォントをOS標準にする

import wx

# OS標準のGUIフォントを取得
default_font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)

# ラベル (self.my_label) に設定
self.my_label.SetFont(default_font)

GetMetric(index, win=None) – OSのUI部品サイズ(メトリクス)を取得する

GetMetric は、OSが定義するUI部品の標準的な寸法や、画面の解像度などをピクセル単位の整数で取得します。

index には、どのサイズが欲しいかを示す定数を指定します。win 引数は通常 None のままで問題ありません。

よく使うメトリクス(寸法)の定数

  • wx.SYS_SCREEN_X, wx.SYS_SCREEN_Y: プライマリモニタの画面解像度(幅と高さ)。
  • wx.SYS_VSCROLL_X: 垂直スクロールバーの「幅」。
  • wx.SYS_HSCROLL_Y: 水平スクロールバーの「高さ」。
  • wx.SYS_CAPTION_Y: ウィンドウのタイトルバーの「高さ」。
  • wx.SYS_FRAMESIZE_X, wx.SYS_FRAMESIZE_Y: ウィンドウのボーダー(枠)の太さ(幅と高さ)。

コード例: 垂直スクロールバーの幅を取得する

import wx

# 垂直スクロールバーの標準的な幅 (pixel) を取得
scroll_width = wx.SystemSettings.GetMetric(wx.SYS_VSCROLL_X)

print(f"このOSのスクロールバーの幅: {scroll_width} px")

# 例えば、レイアウト計算 (Sizer) でこの幅を考慮することができる
# self.my_sizer.AddSpacer(scroll_width)

実践!OSのテーマカラーに追従するカスタムUIの作成

wx.SystemSettings の真価は、OSのテーマ変更(例: ライトモード ⇔ ダークモードの切り替え)に動的に追従できる点にあります。

ここでは、GetColour を使ってOSのテーマカラーを反映し、さらにテーマ変更イベント wx.EVT_SYS_COLOUR_CHANGED を検知してリアルタイムに見た目を更新するサンプルコードを紹介します。

import wx

class MyThemePanel(wx.Panel):
    """
    OSのテーマカラーに自動で追従するカスタムパネル
    """
    def __init__(self, parent):
        super().__init__(parent)
        
        self.label = wx.StaticText(self, label="このパネルはOSのテーマに追従します")
        
        # 起動時に一度、色を適用する
        self.UpdateTheme()
        
        # --- (重要) OSのテーマ変更イベントをバインド ---
        # ユーザーがOSの設定でライト/ダークを切り替えたら OnSysColourChanged を呼ぶ
        self.Bind(wx.EVT_SYS_COLOUR_CHANGED, self.OnSysColourChanged)

    def OnSysColourChanged(self, event):
        """OSのテーマカラーが変更されたときに呼ばれる"""
        print("OSのテーマが変更されました!色を更新します。")
        self.UpdateTheme()
        
        # イベントが親ウィンドウにも伝わるようにする
        event.Skip()

    def UpdateTheme(self):
        """現在のOSテーマカラーをUIに適用する"""
        
        # GetColour を使ってOS標準色を取得
        # (SYS_COLOUR_WINDOW: パネル背景色, SYS_COLOUR_BTNTEXT: テキスト色)
        bg_colour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)
        text_colour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNTEXT)
        
        # パネルとラベルに色を設定
        self.SetBackgroundColour(bg_colour)
        self.label.SetForegroundColour(text_colour)
        
        # 変更を即時反映
        self.Refresh()


class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(None, title="wx.SystemSettings デモ")
        
        panel = MyThemePanel(self)
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(panel, 1, wx.EXPAND)
        self.SetSizer(sizer)
        
        self.SetSize((400, 300))
        self.Centre()

# アプリの実行
if __name__ == "__main__":
    app = wx.App()
    frame = MyFrame()
    frame.Show()
    app.MainLoop()

このコードを実行し、アプリを起動したままOSの「ライトモード」と「ダークモード」を切り替えてみてください。アプリが即座に反応し、パネルの背景色とテキスト色がOSの設定に合わせて自動で切り替わることが確認できるはずです。

まとめ

この記事では、wxPythonアプリの「ネイティブ感」を高めるために不可欠な wx.SystemSettings の使い方を解説しました。

  • 色(#FFFFFF)やフォント名("MS UI Gothic")のハードコーディングは避けましょう
  • OSの標準的な設定値を取得するには wx.SystemSettings を使います。
  • GetColour(index): OSのテーマカラー(wx.SYS_COLOUR_WINDOW など)を取得します。
  • GetFont(index): OSの標準フォント(wx.SYS_DEFAULT_GUI_FONT など)を取得します。
  • GetMetric(index): OSのUI部品のサイズ(wx.SYS_VSCROLL_X など)を取得します。

wx.SystemSettings を適切に使いこなし、ユーザーの環境設定に自動で馴染む、高品質なアプリケーションを目指しましょう。

コメント

タイトルとURLをコピーしました