こんにちは、くのへです。
ここから、日常作業が楽になる「Pythonデスクトップ簡易アプリ10選」を投稿していきます。
しかも、このアプリを開発を通して、Pythonのライブラリなどを勉強して習得してしまおう!という企画です。
是非、一緒に楽しんで走って頂きたいと思います。
また、CursorやVScode(GitHubCopilot)を使っている方は、生成AIに作って貰ったはいいけど、コードが全然わからない!!ということもあろうと思います。
その方も、この記事でライブラリを習得すると、コードが読めるようになるんじゃないかな、と思います!
なお、デスクトップで.pyや.pywを動かす設定や、生成AI CursorでPythonを使う設定については、この↓動画をご参照ください
1本目はデスクトップに日付フォルダを一発作成するコードでしたが、今回はファイル名を入力するウィンドウを出して、そのウィンドウに名前を記入したら、「yyyymmdd_ファイル名」のフォルダを作るコードを作成します。
このコードを作成する価値で、tkinter(ティーケーインター、またはティーキンターと読む)ライブラリの基本を習得します!
作成する内容とコード
今回作成するプログラムは次のようなプログラムです。この条件をCursorに与えたらすぐに出来ちゃいます。
◆「yyyymmdd_フォルダ名」形式の空のフォルダを作成する
①.pyまたは.pywをダブルクリックすると、デスクトップに「yyyymmdd_フォルダ名」形式のフォルダを生成する
②yyyymmddは今日の日付とする。
③フォルダ名はインプットボックスを表示してユーザに記入させる
④もしもユーザがキャンセルまたは無記名だった場合はフォルダ作成はキャンセルとする
⑤もしも既に同名フォルダがある場合は、yyyymmdd(1)のように通し番号を付ける
コード
コピペで動くと思います。
Python3をインストールの上、ファイル拡張子は.pyか.pywで実行下さい。
インプットボックスが表示されている間、コンソールが表示されてしまいますので、.pywの方を推奨します。
import os
import datetime
import tkinter as tk
from tkinter import simpledialog
today = datetime.date.today()
date_str = today.strftime("%Y%m%d")
desktop_path = os.path.expanduser("~/Desktop")
root = tk.Tk()
root.withdraw() # メインウィンドウを表示しない
folder_name_input = simpledialog.askstring("フォルダ名入力", "フォルダ名を入力してください")
if folder_name_input:
folder_name = f"{date_str}_{folder_name_input}"
folder_path = os.path.join(desktop_path, folder_name)
counter = 1
while os.path.exists(folder_path):
folder_name = f"{date_str}_{folder_name_input}({counter})"
folder_path = os.path.join(desktop_path, folder_name)
counter += 1
os.makedirs(folder_path)
解説
このコードは前回の記事のコードから朱記部を変更したものです。
import os
import datetime
import tkinter as tk
from tkinter import simpledialog
today = datetime.date.today()
date_str = today.strftime("%Y%m%d")
desktop_path = os.path.expanduser("~/Desktop")
root = tk.Tk()
root.withdraw()
folder_name_input = simpledialog.askstring("フォルダ名入力", "フォルダ名を入力してください")
if folder_name_input:
folder_name = f"{date_str}_{folder_name_input}"
folder_path = os.path.join(desktop_path, folder_name)
counter = 1
while os.path.exists(folder_path):
folder_name = f"{date_str}_{folder_name_input}({counter})"
folder_path = os.path.join(desktop_path, folder_name)
counter += 1
os.makedirs(folder_path)
tkinterライブラリ
tkinterライブラリはインプットボックスやウィンドウのようなGUIを手軽に作成できるライブラリです。
これが使えると、一気におしゃれになります。
なお、Pythonをインストールすると標準でライブラリはインストールされますが、インポートしないと使えないため、コードの頭でインポートします。インポートする時には「tk」という略称が用いられることが多いです。
◆基本的な使い方
tkinterでウィンドウを作る時の基本的な使い方は次の通りです
①Tkクラスのインスタンス(ウィンドウ)を作成する。「root」という名前にする人が多い。
②root.titleなどのプロパティを記載
③ラベルやボタンなどの部品オブジェクトを作り、pack()、grid()、place()で配置(それぞれ簡易配置、グリッド配置、絶対配置)
④root.mainloop()で実行すると作ったウィンドウが開かれる。ウィンドウが消えるまでプログラムはこの行をひたすら実行する。
⑤最後にウィンドウを×ボタンで閉じるか、コードでroot.destroy()と命令すればアプリを終了させることが出来る
次のコードを実行してみると使い方が分かりやすいと思います。
import tkinter as tk
root = tk.Tk()
root.title("Widget Example") #ウィンドウタイトル
root.geometry("300x200") #ウィンドウサイズ
# ラベルの作成と配置
label = tk.Label(root, text="Hello, Tkinter!", font=("Arial", 16))
label.pack() # 自動で配置される
# ボタンの作成と配置
def on_button_click():
label.config(text="Button Clicked!")
button = tk.Button(root, text="Click Me", command=on_button_click)
button.pack()
root.mainloop()
とここまで書きましたが、tkinterのラベルやボタンって、初心者にとってかなり難しいんですよね!!
私はこれから入門するのは反対です。
今回のテーマのコードのような、シンプルなインプットボックスやメッセージボックスを使う所から学んだらいいと思います。
シンプルなインプットボックス・メッセージボックスの場合、tkinterライブラリの「simpledialogモジュール」「messageboxモジュール」に既存の部品があるので、これを使えば簡単にウィンドウを実装出来ます。
これを使う方法は次の通り。(simpledialogモジュールを代表として説明)
①コードの最初に「import tkinter as tk」だけではなく「from tkinter import simpledialog」と書く。これを書けば直接コードにsimpledialogでコードを書ける。
②Tkクラスのインスタンス(ウィンドウ)を作成する。「root」という名前にする人が多い。これが「親ウィンドウ」になる。
③root.withdraw()と命令する。これで親ウィンドウが非表示になる。
④変数=simpledialog.askstring(ウィンドウ名, 入力欄に記載される文字) と書いてインプットボックスを表示する。
ここで、④においてsimpledialog.askstring()を使うと、親ウィンドウの配下としてインプットボックスが同時に表示されますがが、③をやっておくと親ウィンドウは表示させずに、インプットボックスだけを表示できます。
なお、ユーザに記入された文字は変数の中に格納されます。
コードを改めてみてみると、simpledialog.askstringという命令を使ってインプットボックスを表示して入力させていることが分かると思います。
import os
import datetime
import tkinter as tk
from tkinter import simpledialog
today = datetime.date.today()
date_str = today.strftime("%Y%m%d")
desktop_path = os.path.expanduser("~/Desktop")
root = tk.Tk()
root.withdraw()
folder_name_input = simpledialog.askstring("フォルダ名入力", "フォルダ名を入力してください")
if folder_name_input:
folder_name = f"{date_str}_{folder_name_input}"
folder_path = os.path.join(desktop_path, folder_name)
counter = 1
while os.path.exists(folder_path):
folder_name = f"{date_str}_{folder_name_input}({counter})"
folder_path = os.path.join(desktop_path, folder_name)
counter += 1
os.makedirs(folder_path)
1か所難しいのは「if folder_name_input:」ですね。ここはインプットボックスに何も入力されなければ、folder_name_inputが「無」、すなわちFalseになるため、ifの中の処理は行われません。
この仕組みで、未記入やキャンセルの場合には動作させないようにしています。
simpledialogなどについて
なお、simpledialogは主に次のような命令があります。
simpledialog.askstring ⇒ 文字列を入力するダイアログボックス
simpledialog.askinteger ⇒ 整数を入力するダイアログボックス
simpledialog.askfloat ⇒ 浮動小数を入力するダイアログボックス
simpledialogに似た機能にmessageboxもあります。
これもsimpledialogと同様にrootを親ウィンドウとしてroot.withdraw()で非表示にして使います。
使用例)
import tkinter as tk
from tkinter import messagebox
# メインウィンドウを作成
root = tk.Tk()
root.withdraw() # メインウィンドウは非表示にする
# Yes/Noダイアログを表示
result = messagebox.askyesno("Confirm", "Do you want to continue?")
# 結果を表示
if result:
print("User selected Yes")
else:
print("User selected No")
root.mainloop()
messageboxにはaskyesnoも含めて、以下の様な命令があります。
messagebox.askyesno ⇒ Yes/No
messagebox.askokcancel ⇒ OKまたはキャンセル
messagebox.askretrycancel ⇒ 再試行またはキャンセル
messagebox.showinfo ⇒ 情報を表示するダイアログ(ユーザに選択肢は無い)
messagebox.showwarning ⇒ 警告を表示するダイアログ
messagebox.showerror ⇒ エラーを表示するダイアログ
VBAユーザの方は、messageboxがmsgboxに相当し、simpledialogがinputboxに相当すると思ったらいいのではないかなと思います。
ちょっと難しい話
ところで、simpledialog.askstring(・・・)とrootって全く関係ないように見えませんか?
もしもroot.simpledialog.askstring(・・・)となっているなら、なんとなく分かるんですが、、、
この件について、ちょっと難しいのですが、simpledialog.askstring()にはやっぱりrootは使われているのです。
tkinter.simpledialog.askstringは内部でtk.Tk()や他のTkインスタンスを使用して動作します。
明示的にparent引数を指定しない場合、simpledialog.askstringは、tk._default_rootという特殊な変数を利用してrootウィンドウを自動的に取得します。(なんてマニアックな、、、)
そして、最初にtk.Tk()を呼び出すと、そのインスタンスがtk._default_rootに設定されます。
その後、simpledialog.askstringなどの関数を呼び出すと、_default_rootを親ウィンドウとして自動的に使用します。
ということで、最初に設定したroot = tk.Tk()のrootがsimpledialog.askstringの親ウィンドウとして使用されます。
だから、root = tk.Tk() をコードから削除することは出来ないし、root.withdraw()で非表示にしておかないと、simpledialog.askstringの時点で謎のウィンドウが出ちゃうんだね。
最後に
本記事を読んで頂きありがとうございます。
2本目にしてtkinterを紹介しました。
tkinterは機能が多く、ラベルやボタンを先にやるとちょっと難しいんですよね。
まずはsimpledialogやmessageboxを使って慣れましょう!
最初のroot=tk.Tk()やroot.withdraw()は呪文だと思っていいと思います!