こんにちは、くのへです!
Pythonを使ってデスクトップの背景画像を簡単に変更できる、便利なアプリを作ってみましょう。
このアプリを使えば、お気に入りの画像をすぐにデスクトップの背景に設定できます。
今回のアプリ開発を通して、以下の内容を学習できます。
- def による関数の定義と呼び出し
- Pythonの特殊な書き方 if __name__ == “__main__”: の意味と使い方
- tkinter の filedialog モジュールを使ってファイル選択ウィンドウを表示する方法
- ctypes ライブラリを使ってWindowsのシステム関数を呼び出す方法
- 16進数表記の基礎知識
さあ、一緒に便利アプリを作っていきましょう!
この記事の解説動画はこちらです
今回作成するコード
まずは、今回作成するPythonコード全体を見てみましょう。
import tkinter as tk
from tkinter import filedialog
import ctypes
def change_background():
root = tk.Tk()
root.withdraw()
file_path = filedialog.askopenfilename(title="背景画像を選択", filetypes=[("画像ファイル", "*.png *.jpg *.jpeg *.bmp")])
if file_path:
SPI_SETDESKWALLPAPER = 0x0014
ctypes.windll.user32.SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, file_path, 3)
if __name__ == "__main__":
change_background()
コード解説
では、コードの各部分を詳しく見ていきましょう。
def (関数化)
Pythonでは、defキーワードを使って独自の関数を定義できます。
def change_background():
# ここに処理を記述
def は define (定義する) の略です。これにより、一連の処理をまとめて名前をつけ、必要なときにその名前で呼び出すことができるようになります。
関数化することで、コードの見通しが良くなり、同じ処理を何度も書く必要がなくなります。今回のコードでは、背景画像を変更する一連の処理を change_background() という関数として定義しています。
if __name__ == “__main__”:
次に、多くのPythonスクリプトの最後に見られる特殊な書き方です。
if __name__ == "__main__":
change_background()
IGNORE_WHEN_COPYING_START content_copy download Use code with caution. Python
IGNORE_WHEN_COPYING_END
これはPython特有の仕組みで、__name__という特殊な変数を使っています。
__name__変数には、スクリプトがどのように実行されたかに応じて異なる値が代入されます。
- スクリプトを直接実行した場合: __name__には “__main__” という文字列が代入されます。
- 他のスクリプトからモジュールとしてインポートされた場合: __name__にはそのスクリプトのファイル名(モジュール名)が代入されます。
したがって、if __name__ == “__main__”:という条件式は、「このスクリプトが直接実行された場合にのみ、if文の中の処理を実行する」という意味になります。
関数を定義したスクリプトでこの書き方をしておくと、関数をテストするためにスクリプトを直接実行したときは意図した処理(今回の場合はchange_background()の呼び出し)が動き、他のプログラムからこのスクリプトをインポートして中の関数だけを使いたいときは、if文の中の処理は実行されない、といった使い分けができます。
個人的には、特に複数の関数を含むスクリプトで、どこがプログラムの開始点であるメイン処理なのかを判断しやすくなるため、可読性が上がる書き方だと感じています。
tkinterのfiledialogモジュール
tkinterはPythonでGUI(Graphical User Interface)を持つアプリケーションを作成するための標準ライブラリです。
その中のfiledialogモジュールは、ファイルを開いたり保存したりするための標準的なダイアログウィンドウを提供します。
今回のコードでは、画像ファイルを選択するために filedialog.askopenfilename() 関数を使っています。
root = tk.Tk()
root.withdraw() # 親ウィンドウを非表示にする
file_path = filedialog.askopenfilename(title="背景画像を選択", filetypes=[("画像ファイル", "*.png *.jpg *.jpeg *.bmp")])
if file_path:
# ファイルパスを使った処理
pass # 例
IGNORE_WHEN_COPYING_START content_copy download Use code with caution. Python
IGNORE_WHEN_COPYING_END
- root = tk.Tk() と root.withdraw(): 通常、tkinterでダイアログを使うにはルートウィンドウが必要ですが、ファイルダイアログだけを表示したい場合は、このようにルートウィンドウを作成してすぐに非表示にするのが一般的な方法です。
- filedialog.askopenfilename(): ファイルを開くためのダイアログを表示し、ユーザーが選択したファイルのパスを返します。もしユーザーがキャンセルした場合は、空文字列が返されます。
- title: ダイアログのタイトルバーに表示される文字列を指定します。
- filetypes: ユーザーが選択できるファイルの種類のフィルタリングを設定します。今回は画像ファイル(.png, .jpg, .jpeg, .bmp)のみが表示されるように設定しています。
- 戻り値はfile_pathという変数に代入され、これは選択されたファイルの絶対パスとなります。
- if file_path:: ファイルが選択されず、file_pathが空文字列の場合は、その後の背景変更処理を行わないようにしています。
ctypesライブラリとSystemParametersInfoW関数
デスクトップの背景画像を変更する処理は、Pythonの標準機能では直接行うことができません。
WindowsのOSが提供する機能を利用する必要があります。
ctypesライブラリは、PythonからC言語などで書かれた共有ライブラリ(WindowsではDLLファイル)内の関数を呼び出すためのライブラリです。
今回のコードでは、user32.dllというWindowsのシステムDLLに含まれるSystemParametersInfoW関数を利用しています。
# SPI_SETDESKWALLPAPER はデスクトップの壁紙を設定するための値
SPI_SETDESKWALLPAPER = 0x0014
# ctypesを使ってwindowsのuser32.dllにあるSystemParametersInfoW関数を呼び出す
ctypes.windll.user32.SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, file_path, 3)
IGNORE_WHEN_COPYING_START content_copy download Use code with caution. Python
IGNORE_WHEN_COPYING_END
- ctypes.windll.user32: Windowsのuser32.dllをロードしています。
- SystemParametersInfoW: user32.dll内にある特定の関数を呼び出しています。この関数は、システムの様々な設定(ディスプレイ、マウス、キーボード、スクリーンセーバーなど)を取得または変更するために使われます。
- 引数について:
- 第1引数 (SPI_SETDESKWALLPAPER = 0x0014): どのシステム設定を操作するかを指定する値です。SPI_SETDESKWALLPAPERという定数は、「デスクトップの壁紙を設定する」という操作に対応しています。
- 第2引数 (0): 操作によっては追加の情報が必要ですが、壁紙設定の場合はこの引数は使用しないため0を指定します。
- 第3引数 (file_path): 操作に必要な情報を渡します。壁紙設定の場合は、新しい壁紙のファイルパスを渡します。
- 第4引数 (3): 操作の反映方法などを指定するフラグです。3は設定変更をすぐに反映させ、ユーザープロファイルにも保存するという意味になります。
このようなシステムAPIの詳細(関数名、引数の意味、定数の値など)は、通常はWindows APIのリファレンスなどを調べて確認する必要があります。しかし、最近の生成AIを利用すると、やりたいことを伝えれば適切なAPIやその使い方のコードを提案してくれることが多く、以前に比べて調べ物のコストは下がっています。
コードに出てきた0x0014のような表記は、16進数表記です。
- 0x から始まる数字は「16進数」で表現されていることを示します。
- つまり、0x0014 は16進数で書かれた数値を意味します。
この16進数を10進数に変換すると、以下のようになります。
0×163+0×162+1×161+4×1600 \times 16^3 + 0 \times 16^2 + 1 \times 16^1 + 4 \times 16^00×163+0×162+1×161+4×160
=0×4096+0×256+1×16+4×1= 0 \times 4096 + 0 \times 256 + 1 \times 16 + 4 \times 1=0×4096+0×256+1×16+4×1
=0+0+16+4= 0 + 0 + 16 + 4=0+0+16+4
=20= 20=20
したがって、0x0014 は 10進数で 20 と同意になります。
似た概念に「2進数表記」があり、0b から始まる数字で表現されます。(例: 0b00010100 も 10進数で20です)
2進数表記は、電子工作など低レベルのハードウェアに近いプログラミングでたまに使われることがあります。
まとめ
今回はPythonを使ってデスクトップの背景画像をパッと変更するアプリを作成しました。
- def による関数化を学び、処理をまとめて整理できるようになりました。
- Pythonの特殊な書き方 if __name__ == “__main__”: を使い、スクリプトの直接実行時とインポート時で処理を分ける方法を知りました。
- tkinter の filedialog モジュールで、画像ファイルを選択するファイル選択ウィンドウを表示し、選択されたファイルのパスを取得しました。
- ctypes ライブラリを使い、PythonからC言語で書かれたWindowsのシステム関数(SystemParametersInfoW)を呼び出して、デスクトップの背景画像を実際に変更しました。また、その中で使われる16進数表記についても触れました。
今回の内容は少し難しかったかもしれませんが、ここで学んだ def や if __name__ == “__main__”: は、今後のPythonプログラミングでも頻繁に登場する非常に重要な概念です。ぜひ繰り返し練習して身につけてください。
おわりに
Python便利アプリシリーズ、6本目お疲れ様でした!
今回学んだ関数化やモジュール、ライブラリの利用といった内容は、今後のアプリ開発でも役立つはずです。
7本目以降も、これらの知識を活かして様々な便利アプリを作っていきましょう。
それでは、また別の記事をお楽しみに!
バイバイ!