👏

【Tkinter】Batファイルの実行結果を背景に表示

に公開

概要

Tkinterでツール作成時に いつも表示されていたら便利だな~って思うものはありませんか。
例えばバージョン、ビルド日・・・・色々あると思います。

今回は sampleで用意した bat ファイルを実行したときの標準出力をTkinterの背景に表示するプログラムを紹介します。

サンプルコード1(Python)

import tkinter as tk
import subprocess

def get_version_info():
    bat_path = r"version_display.bat"  # 同じフォルダの場合
    try:
        result = subprocess.run(
            [bat_path, "-version"],
            capture_output=True,
            text=True,
            shell=True,
            encoding="utf-8",
            errors="replace"
        )
        if result.returncode == 0:
            return result.stdout.strip()
        else:
            return "バージョン情報取得失敗"
    except Exception as e:
        return f"バージョン情報取得エラー: {e}"

root = tk.Tk()
root.title("バージョン表示サンプル")
root.geometry("400x200")

# バージョン情報取得
version_info = get_version_info()

# 日本語フォントを明示的に指定
version_label = tk.Label(
    root,
    text=version_info,
    anchor="se",
    justify="right",
    fg="gray",
    font=("Meiryo", 10)  # ← ここを追加
)
version_label.place(relx=1.0, rely=1.0, anchor="se", x=-10, y=-10)  # 右下に余白付きで配置

root.mainloop()
root.mainloop()

サンプルコード2(Bat)

version_display.bat -version で実行すると諸々表示してくれるだけのBat
(検証用のサンプルなので適当内容)

@echo off
chcp 65001 >nul
setlocal

REM バージョン表示
if "%1"=="-version" goto :showver

REM 他の処理があればここに記載
echo Usage: %~nx0 -version
exit /b 1

:showver
echo 製品名: サンプルアプリケーション
echo バージョン: 2.3.1
echo ビルド日: 2024-06-19
echo 著作権: (C) 2024 Example Corp. All rights reserved.
echo Javaバージョン: 17.0.10
echo Pythonバージョン: 3.11.4
exit /b 0

サンプルコード2の実行例

・こんな感じに表示される。

.\version_display.bat -version
製品名: サンプルアプリケーション
バージョン: 2.3.1
ビルド日: 2024-06-19
著作権: (C) 2024 Example Corp. All rights reserved.
Javaバージョン: 17.0.10
Pythonバージョン: 3.11.4

今回はこの表示された内容をTkinterに表示させるという内容です。

実際に起動するとこんな感じに表示されます。

※一部の環境では以下の問題が起きる可能性あり(私はWindowsで実行した)
batを実行しても標準出力されない。
Tkinterに表示される内容が文字化けしている。
など・・・・。
これはScriptでBatを実行してその結果を受け取るときの文字コードがおかしいことが原因っぽい。
Batの実行結果はSJISで渡されるっぽいので今回はUTF-8を強制的に指定して防いだ。

応用編1(バージョン関連だけ見たい)

・実際のところ、バージョンだけ見れればいいんだけど・・・ってときは以下のコードでOK

import tkinter as tk
import subprocess

def get_version_lines(keyword="バージョン:"):
    bat_path = r"version_display.bat"
    try:
        result = subprocess.run(
            [bat_path, "-version"],
            capture_output=True,
            text=True,
            shell=True,
            encoding="utf-8",
            errors="replace"
        )
        if result.returncode == 0:
            # 行ごとに分割し、キーワードを含む行だけ抽出
            lines = result.stdout.splitlines()
            filtered = [line for line in lines if keyword in line]
            return "\n".join(filtered) if filtered else "該当情報なし"
        else:
            return "バージョン情報取得失敗"
    except Exception as e:
        return f"バージョン情報取得エラー: {e}"

root = tk.Tk()
root.title("バージョン情報抽出サンプル")
root.geometry("400x200")

# 例: 「バージョン:」を含む行だけ表示
version_info = get_version_lines("バージョン:")

version_label = tk.Label(
    root,
    text=version_info,
    anchor="se",
    justify="right",
    fg="gray",
    font=("Meiryo", 10)
)
version_label.place(relx=1.0, rely=1.0, anchor="se", x=-10, y=-10)

root.mainloop()

表示例

・こんな感じになる。

応用編2(Pythonのバージョン表示を追加)

import tkinter as tk
import subprocess
import sys

def get_version_info():
    bat_path = r"version_display.bat"  # 同じフォルダの場合
    try:
        result = subprocess.run(
            [bat_path, "-version"],
            capture_output=True,
            text=True,
            shell=True,
            encoding="utf-8",
            errors="replace"
        )
        if result.returncode == 0:
            return result.stdout.strip()
        else:
            return "バージョン情報取得失敗"
    except Exception as e:
        return f"バージョン情報取得エラー: {e}"

def get_installed_python_version():
    try:
        result = subprocess.run(
            [sys.executable, "--version"],
            capture_output=True,
            text=True,
            encoding="utf-8",
            errors="replace"
        )
        if result.returncode == 0:
            return f"インストール済みPython: {result.stdout.strip()}"
        else:
            return "インストール済みPythonバージョン取得失敗"
    except Exception as e:
        return f"インストール済みPythonバージョン取得エラー: {e}"

root = tk.Tk()
root.title("バージョン表示サンプル")
root.geometry("400x250")

# バージョン情報取得
version_info = get_version_info()
python_version = get_installed_python_version()

# 日本語フォントを明示的に指定
version_label = tk.Label(
    root,
    text=version_info,
    anchor="nw",
    justify="left",
    fg="gray",
    font=("Meiryo", 10)
)
version_label.place(relx=0.0, rely=0.0, anchor="nw", x=10, y=10)

python_label = tk.Label(
    root,
    text=python_version,
    anchor="sw",
    justify="left",
    fg="blue",
    font=("Meiryo", 10)
)
python_label.place(relx=0.0, rely=1.0, anchor="sw", x=10, y=-10)

root.mainloop()

Pythonのバージョン表示例

・↓こんな感じで表示される。

Discussion