PR

DearPyGuiのフォント設定と文字サイズの変え方|日本語が『?』になる原因と2.3の変更点

Python
DEARPYGUI GUIDE VOL.3
スポンサーリンク

DearPyGuiのフォント設定と文字サイズの変え方

ニンジンです🥕

DearPyGuiシリーズの3回目は、フォントの設定と文字サイズの変え方です。

🥕 シリーズ第1回 DearPyGuiの使い方|pipでのインストールから日本語表示・画面の作り方まで インストールから、add_font・bind_font での日本語フォントの基本までをまとめた入門編。 →

DearPyGuiは、2.3でフォントまわりの仕組みが大きく変わりました。ネットの記事やAIが書くコードには2.2以前の書き方が多く、そのまま使うと「動くけど何かおかしい」ことが起きます。この記事では、2.2と2.3.1を同じWindowsで動かして、実際の画面で違いを比べました。

先に結論

  • フォントは add_font() で登録して bind_font() するだけでよい(2.3以降は add_font_range_hint() は不要)
  • 文字サイズは、add_font() のサイズ指定、bind_item_font()、set_global_font_scale() の3通りで変えられる。2.3以降は、全体の拡大でもくっきり表示される
  • Windowsでは、日本語を含むフォルダにあるフォントは読み込めない。半角英数字の名前のフォルダに置き、相対パスで指定する

確認環境

  • Windows 11 25H2(日本語版)
  • Python 3.13.13(64bit)
  • dearpygui 2.3.1(比較用に 2.2)
  • フォント:游ゴシック(C:\Windows\Fonts\YuGothM.ttc)

この記事で使ったスクリプトは、まとめてダウンロードできます。

📦 dearpygui003-scripts.zip をダウンロード

(font_custom.py / font_size_slider.py / font_jp_path_test.py / font_path_workaround_test.py / font_relative_path.py / font_version_test.py / README.txt)


スポンサーリンク

1. DearPyGuiに最初から入っているフォント(ProggyClean)

フォントを何も設定しないと、DearPyGuiはDear ImGuiに組み込まれている「ProggyClean」というフォントを使います(v2.3.1のソース src/mvFontManager.cpp の171〜174行目で確認。この記事の行番号は、どれも書いてあるバージョンのものです)。英数字用の小さなフォントなので、日本語は ? になります。

フォントを設定していない画面

▲ フォントを設定していない画面

日本語を表示したいときや、文字を大きくしたいときは、自分でフォントを登録します。


スポンサーリンク

2. フォントを変える(add_font・bind_font・bind_item_font)

import dearpygui.dearpygui as dpg

FONT = r"C:\Windows\Fonts\YuGothM.ttc"  # 游ゴシック

dpg.create_context()

with dpg.font_registry():
    normal = dpg.add_font(FONT, 18)  # 普段の文字
    large = dpg.add_font(FONT, 28)   # 見出し用
dpg.bind_font(normal)                # アプリ全体に 18px を使う

with dpg.window(tag="main"):
    title = dpg.add_text("見出し(28px)")
    dpg.bind_item_font(title, large)  # この部品だけ 28px にする
    dpg.add_text("本文(18px)。アプリ全体には bind_font で 18px を設定しています。", wrap=380)
    btn = dpg.add_button(label="大きいボタン")
    dpg.bind_item_font(btn, large)
    dpg.add_button(label="普通のボタン")

dpg.create_viewport(title="Font Custom", width=440, height=220)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.set_primary_window("main", True)
dpg.start_dearpygui()
dpg.destroy_context()
font_custom.pyの実行結果
▲ font_custom.pyの実行結果
  • with dpg.font_registry(): の中で、add_font(フォントファイル, サイズ) でフォントを登録します
  • bind_font() で、アプリ全体に使うフォントを決めます
  • bind_item_font(部品, フォント) で、その部品だけ別のフォントにできます

同じフォントファイルでも、サイズごとに add_font() で登録します。画像では、見出しと「大きいボタン」だけが28pxになっています。

Windowsのフォントは C:\Windows\Fonts にあります。この記事では游ゴシックの YuGothM.ttc を使っています。


スポンサーリンク

3. 文字サイズを変える(font size)

文字サイズの変え方は、次の3通りです。

方法変わる範囲使いどころ
add_font(ファイル, サイズ) のサイズを変えるそのフォントを使う部分最初から決まったサイズで表示したい
bind_item_font() で大きいフォントを割り当てる指定した部品だけ見出しやボタンだけ大きくしたい
set_global_font_scale(倍率)アプリ全体利用者が文字の大きさを変えられるようにしたい

スライダーで文字サイズを変える

set_global_font_scale() を使うと、アプリを動かしたまま文字の大きさを変えられます。

import dearpygui.dearpygui as dpg

FONT = r"C:\Windows\Fonts\YuGothM.ttc"


def on_scale(sender, app_data, user_data):
    dpg.set_global_font_scale(app_data)       # アプリ全体の文字の倍率を変える
    dpg.set_value("scale_text", f"倍率: {app_data:.1f}")


dpg.create_context()
with dpg.font_registry():
    font = dpg.add_font(FONT, 18)
dpg.bind_font(font)

with dpg.window(tag="main"):
    dpg.add_slider_float(label="文字の倍率", default_value=1.0, min_value=0.5, max_value=2.0, format="%.1f",
                         width=200, callback=on_scale)
    dpg.add_text("倍率: 1.0", tag="scale_text")
    dpg.add_text("スライダーを動かすと、アプリ全体の文字の大きさが変わります")
    dpg.add_button(label="ボタンの文字も変わる")

dpg.create_viewport(title="Font Size", width=560, height=260)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.set_primary_window("main", True)
dpg.start_dearpygui()
dpg.destroy_context()
倍率1.0
▲ 倍率1.0
倍率2.0
▲ 倍率2.0

2倍にしても、文字はくっきりしています。ただ、width=200 で指定したスライダーの幅は変わらず、長い文はウィンドウからはみ出しています。部品の幅はピクセルで指定しているので、全体を拡大するときは、ウィンドウや部品の幅にも気を配る必要があります。

2.2では、拡大するとぼやける

同じ set_global_font_scale(2.0) を2.2で動かすと、文字がぼやけます。18pxで登録して2倍にした画面です。

2.2で2倍に拡大
▲ 2.2で2倍に拡大
2.3.1で2倍に拡大
▲ 2.3.1で2倍に拡大

ソースを比べると、全体の拡大の仕組みが変わっていました(src/mvContext.cpp。2.2は173行目、2.3.1は185行目)。2.2では Dear ImGui の FontGlobalScale(できあがった文字の画像を引き伸ばす)を使っていましたが、2.3.1では FontScaleMain を使うようになっています。2.3でDearPyGuiの中のDear ImGuiが1.92系に更新されたことによる変化です(2.2は1.91.0、2.3.1は1.92.5)。

2.2で文字を大きくしたいときは、全体の拡大ではなく、最初から大きいサイズで add_font() してください。36pxで登録した場合は、2.2でもくっきり表示されました。

2.2で36pxで登録
▲ 2.2で36pxで登録

スポンサーリンク

4. 日本語が「?」になる原因と add_font_range_hint

2.2と2.3.1の比較

2.2と2.3.1で、次の3通りの書き方を試しました。

  • フォントだけ:add_font() で登録するだけ
  • 範囲の指定あり:古い記事でよく見る add_font_range_hint(dpg.mvFontRangeHint_Japanese) を追加
  • 文字の追加あり:さらに add_font_chars() で「髙 﨑 𠮷」を追加

2.2以前でよく使われていた書き方は、次のような形です。

with dpg.font_registry():
    with dpg.font(r"C:\Windows\Fonts\YuGothM.ttc", 20) as font:
        dpg.add_font_range_hint(dpg.mvFontRangeHint_Japanese)
        dpg.add_font_chars([ord(c) for c in "髙﨑𠮷"])
dpg.bind_font(font)

結果は次のとおりです。

表示した文字2.2 フォントだけ2.2 範囲の指定あり2.2 文字の追加あり2.3.1(3通りとも)
ひらがな・カタカナ・よく使う漢字?表示表示表示
鬱?表示表示表示
髙 﨑 𠮷??表示表示
① ㈱???表示
🥕(絵文字)????
2.2 フォントだけ
▲ 2.2 フォントだけ
2.2 範囲の指定あり
▲ 2.2 範囲の指定あり
2.2 文字の追加あり
▲ 2.2 文字の追加あり
2.3.1 フォントだけ
▲ 2.3.1 フォントだけ

2.2より前の版(1.11.1・2.0.0・2.1.1)は、Windowsでは試していませんが、Linuxで同じ比較をしたところ2.2と同じ結果でした。

2.3.1では、フォントを登録するだけで、フォントに入っている文字が全部表示されるようになりました。add_font_range_hint() や add_font_chars() は、2.3.1では中身が空の関数になっていて、書いても何もしません。エラーにはならず、ターミナルに DeprecationWarning が出るだけです。

絵文字は、どの書き方でも ? でした。游ゴシックに絵文字が入っていないためです。

髙橋さんと山﨑さんが「?」になっていた

この比較で気づいたのが、2.2以前の「お決まりの書き方」の落とし穴です。add_font_range_hint(dpg.mvFontRangeHint_Japanese) で読み込まれるのは、よく使う漢字だけでした。「髙橋」の「髙」や「山﨑」の「﨑」、「①」「㈱」のような文字は、エラーも出ずに ? になります。名簿や顧客管理のアプリなら、気づかないまま使ってしまいそうです。

2.2以前でこれを防ぐには、add_font_chars() で必要な文字を1つずつ追加する必要がありました。


スポンサーリンク

5. 日本語を含むフォルダのフォントは読み込めない(Font file could not be found)

自分でダウンロードしたフォントを、プロジェクトのフォルダに置いて使うこともあると思います。ところが、Windowsでは、パスに日本語が含まれていると読み込めませんでした。

Exception: Error: [1000] Message:       Font file could not be found

フォントファイルは確かにあるのに、「見つからない」というエラーです。私の環境では、Googleドライブの「マイドライブ」がパスに入っていたので、これに引っかかりました。

v2.3.1のソース(src/mvFontItems.cpp の90〜97行目)を見ると、フォントを読み込む前に、C++の標準的な方法(std::ifstream)でファイルを開けるか確認しています。Windowsではこの方法に渡したパスが日本語に対応していない形式で扱われるため、日本語を含むパスは開けず、「見つからない」と判断されます。Linuxでは、日本語を含むパスでも読み込めました。

回避策:半角英数字のフォルダ+相対パス

font_path_workaround_test.py で3通り試したところ、日本語を含むパスをそのまま渡す方法はやはりエラーになり、次の2つで読み込めました。

  • フォントを fonts のような半角英数字の名前のフォルダに置き、相対パス(fonts/YuGothM.ttc)で指定する
  • 一時フォルダ(%TEMP%)にコピーして、そのパスを指定する

2つ目は、Windowsのユーザー名が日本語だと一時フォルダのパスにも日本語が入るので、1つ目をおすすめします。

"""
日本語を含むフォルダにあるプロジェクトで、フォントを読み込む方法。

Windows の DearPyGui 2.3.1 では、add_font に日本語を含むパスを渡すと
「Font file could not be found」になる。
フォントを半角英数字の名前のフォルダ(fonts)に置き、相対パスで渡せば読み込める。

使う前に、このファイルと同じ場所に fonts フォルダを作り、
使いたいフォントファイル(例: C:\\Windows\\Fonts\\YuGothM.ttc)をコピーしておく。
"""
import os
import sys
from pathlib import Path

import dearpygui.dearpygui as dpg

# このファイルがある場所をカレントフォルダにする
# (VS Code の▶で実行すると、カレントフォルダがワークスペースの一番上になるため)
os.chdir(Path(__file__).resolve().parent)

FONT = "fonts/YuGothM.ttc"  # 半角英数字だけの相対パス

if not Path(FONT).exists():
    sys.exit(f"{FONT} がありません。\n"
             f"{Path.cwd() / 'fonts'} フォルダを作り、フォントファイルをコピーしてください。")

dpg.create_context()
with dpg.font_registry():
    font = dpg.add_font(FONT, 20)
dpg.bind_font(font)

with dpg.window(tag="main"):
    dpg.add_text("相対パスでフォントを読み込めました")
    dpg.add_text(f"カレントフォルダ: {Path.cwd().name}")

dpg.create_viewport(title="Font Relative Path", width=520, height=140)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.set_primary_window("main", True)
dpg.start_dearpygui()
dpg.destroy_context()
font_relative_path.pyの実行結果

▲ font_relative_path.pyの実行結果

相対パスは「カレントフォルダ」を基準に探すので、最初に os.chdir() でこのファイルの場所に移しています。VS Codeの▶ボタンで実行すると、カレントフォルダがワークスペースの一番上になるためです。

フォントファイルは配布物に入れていないので、fonts フォルダを作って、使いたいフォントをコピーしてください。


スポンサーリンク

6. AIのコードが静かに壊れるパターン

ここまでの内容を、AIにコードを書いてもらうときの注意点としてまとめます。

  • 2.2以前向けのコードを2.3以降で動かす:add_font_range_hint() は何もしないだけなので、表示は問題ありません。ターミナルに DeprecationWarning が出ます
  • 2.3以降向けのコードを2.2以前で動かす:範囲の指定がないので、日本語が全部 ? になります
  • 2.2で「文字を大きくして」と頼む:set_global_font_scale() を使ったコードが返ってくると、動くけれど文字がぼやけます
  • 2.2以前の「お決まりの書き方」:「髙」「﨑」「①」などが、エラーも出ずに ? になります

どれもエラーが出ないので、気づきにくいのが困るところです。pip install dearpygui==2.3.1 のようにバージョンを固定して、AIにもバージョンを伝えるのが一番の対策です。第1回で配布したテンプレートの AI_RULES.md にも、2.3.1向けの書き方を書いています。

📦 GitHubで配布中 DearPyGui 2.x テンプレート(dearpygui-template) AI_RULES.md に、2.3.1向けのフォントの書き方(add_font_range_hint は書かない)入り。 →

スポンサーリンク

7. コラム:画像の保存(output_frame_buffer)も日本語のパスでは無言で失敗する

この記事の比較画像は、DearPyGuiの output_frame_buffer() で画面を画像に保存して作りました。ところが、最初は保存先に「マイドライブ」が入っていて、画像が1枚も保存されませんでした。エラーも出ず、終了コードも 0 です。

ソースを見ると、画像の保存には同梱の stb_image_write というライブラリを使っていました。このライブラリは、Windowsで日本語のファイル名を扱うには STBIW_WINDOWS_UTF8 という設定が必要です。確認した範囲のDearPyGuiのソースとビルド設定には、この設定が見当たりませんでした。さらに、Windowsで画面を保存する処理(src/mvUtilities_win32.cpp の85行目)では、stbi_write_png() の結果を確認していないので、保存に失敗しても何も言わずに終わります。

半角英数字のパス(一時フォルダ)に保存してから、Pythonの shutil.copy2() でコピーしたら、問題なく保存できました。配布している font_version_test.py は、この方法で保存しています。


スポンサーリンク

DearPyGuiのフォント設定でよくある質問(FAQ)

Q文字を大きくしたら、ぼやけてしまいます

A2.2で set_global_font_scale() を使うと、文字がぼやけます(2.2より前の版は試していません)。2.3以降に上げるか、最初から大きいサイズで add_font() してください(3章)。

Qadd_font_range_hint(dpg.mvFontRangeHint_Japanese) は書いたほうがいいですか?

A2.3以降は不要です。何もしない関数になっていて、書いても DeprecationWarning が出るだけです(4章)。

Q一部の漢字や①が「?」になります

A2.2以前で add_font_range_hint() を使っている場合、よく使う漢字以外は読み込まれません。2.3以降に上げるか、add_font_chars() で文字を追加してください(4章)。

Qフォントファイルはあるのに Font file could not be found になります

AWindowsでは、パスに日本語が含まれていると読み込めません。半角英数字の名前のフォルダに置いて、相対パスで指定してください(5章)。

Q一部の部品だけ文字を大きくできますか?

A大きいサイズのフォントを別に add_font() して、bind_item_font() でその部品に割り当てます(2章)。

Q絵文字は表示できますか?

A游ゴシックには絵文字が入っていないので、? になります。絵文字の入ったフォントは試していません。


スポンサーリンク

まとめ

  • フォントは add_font() で登録して bind_font()。一部だけ変えるなら bind_item_font()
  • 2.3以降は、フォントを登録するだけで日本語も記号も表示される。add_font_range_hint() は不要
  • 2.2以前の書き方では、「髙」「﨑」「①」などがエラーも出ずに ? になっていた
  • 文字サイズは3通りで変えられる。set_global_font_scale() は2.3以降ならくっきり、2.2ではぼやける
  • Windowsでは、日本語を含むパスのフォントは読み込めない。半角英数字のフォルダ+相対パスで回避できる

ぜひ、フォントの設定を見直して、読みやすい画面づくりに役立ててみてください。


DearPyGui Series Navigation

DearPyGuiシリーズ:2.3.1で確かめた書き方と落とし穴


ニンジン🥕アイコン

Follow me on X

本ブログの中の人「ニンジン🥕」はXやってます。新着記事はいち早くポストでお知らせしているので、見逃したくない方は @ninjin_py_vba をフォローしてみてください🥕

@ninjin_py_vba をフォロー

この記事が役に立ったら、シェアしてもらえると嬉しいです🥕

Xでポスト はてブ LINE Pocket
まとめハブ
Python
スポンサーリンク

コメント