【Tkinter開発】第2回 Tkinterで表を作る

Python,エンジニアリングPython,Tkinter

Tkinterでウィンドウが作成できるようになったら、たくさんのリストデータを分かりやすく閲覧できるように、表を配置する。

表に表示させるデータ

適当なデータとしてITmediaのRSSのXMLファイルにする。
https://rss.itmedia.co.jp/rss/2.0/itmedia_all.xml

<item>タグにある

  • タイトル: <title>
  • 詳細: <description>
  • リンク: <link>
  • 日付: <pubDate>

を表の列名とする。

アプリに表を配置する

表ファイルの作成

main.py及びapplication.pyファイルの同階層にtables.pyを作成する。

import tkinter as tk
from tkinter import ttk


class Tables(tk.Frame):
    def __init__(self, master: tk.Tk):
        super().__init__(master)

tk.Frameを継承したTablesクラスを作成し、コンストラクタ__init__()にmasterを受け取るようにする。
from tkinter import ttkは後で使う。

application.pyでは、定義したTablesクラスをインポートする。

import tkinter as tk

from tables import Tables


class Application(tk.Frame):
    def __init__(self, master: tk.Tk):
        super().__init__(master)
        self.title = "Tkinter Application"

        master.geometry("800x600")
        master.title(self.title)

        self.mainframe = tk.Frame(self)
        self.mainframe.grid_rowconfigure(0, weight=1)
        self.mainframe.grid_columnconfigure(0, weight=1)
        self.mainframe.pack()

        self.tables = Tables(self.mainframe)
        self.tables.grid(row=0, column=0, sticky="nsew")

テーブル以外にも配置できるように、mainframeというFrameを置き、そこにTablesを配置している。

もちろん、ここまで書いて起動してもまだ真っ白な画面である。

表の配置

表はttk.Treeeviewクラスを利用して作成する。このクラスでは、配置するウィジェットと列名の一覧を設定する。

class Tables(tk.Frame):
    def __init__(self, master: tk.Tk):
        super().__init__(master)

        # テーブルの作成
        self.create_table()

    def create_table(self):
        # 表の列名
        columns = ["Title", "Description", "Link", "Date"]

        self.treeview = ttk.Treeview(self.master, columns=columns, show="headings")

        # 列名を設定
        for col in columns:
            self.treeview.heading(col, text=col)
            self.treeview.column(col)

        # スクロールバーを追加
        scrollbar = ttk.Scrollbar(
            self.master, orient="vertical", command=self.treeview.yview
        )
        self.treeview.configure(yscrollcommand=scrollbar.set)

        # グリッドに配置
        self.treeview.grid(row=0, column=0, sticky="nsew")
        scrollbar.grid(row=0, column=1, sticky="ns")

        # グリッド設定
        self.master.grid_rowconfigure(0, weight=1)
        self.master.grid_columnconfigure(0, weight=1)

今回はタイトル、詳細、リンク、日付の列を持つ表とするため、columnsは上記のように設定する。

Tkinterのよくあるプログラムの構造として、ウィジェットクラスのメソッドとして関数を定義し、__init__()でその関数を呼び出す。
今回の場合、create_table()関数で表に関する設定及び表示を記述し、__init__()で呼び出している。


ここまで作成すると以下のように空の表ができる。

第2回 表の配置までの画面

表にデータを入れる

表にデータを入れる

class Tables(tk.Frame):
    def __init__(self, master: tk.Tk):
        super().__init__(master)

        # テーブルの作成
        self.create_table()

        # サンプルデータの追加
        sample_data = [
            (
                "「コーヒー苦手民」から安堵の声 マック「定番メニューの販売再開はおそらく初めて」",
                "全国のマクドナルド店舗で23日を最後に姿を消した「ホットティー」の販売が、2月下旬から再開されることになった。",
                "https://www.itmedia.co.jp/business/articles/2401/28/news049.html",
                "Sun, 28 Jan 2024 08:30:00 +0900",
            ),
            (
                "学生がお金を稼ぐためにしたいこと 3位「難関資格の取得」、2位「副業」、1位は?",
                "主に高校生を対象に「お金」をテーマに実施した調査結果が明らかになった。お金を稼ぐためにしたいことや、親と学費の相談をした時期などを調査した。",
                "https://www.itmedia.co.jp/business/articles/2401/28/news020.html",
                "Sun, 28 Jan 2024 08:15:00 +0900",
            ),
            (
                "男性が選ぶかっこいいと思う輸入車 3位「ラングラー」、2位「Sクラス」、1位は?",
                "NEXERが運営する日本トレンドリサーチが、グーネット中古車と共同で「かっこいい輸入車」に関するアンケート調査を実施した。男性が選ぶかっこいいと思う輸入車の1位とは。",
                "https://www.itmedia.co.jp/business/articles/2401/28/news027.html",
                "Sun, 28 Jan 2024 08:00:00 +0900",
            ),
        ] * 10

        # テーブルへデータ挿入
        self.import_table_data(sample_data)

    ...中略...

    def import_table_data(self, data):
        # 既存テーブルのデータを削除
        for item in self.treeview.get_children():
            self.treeview.delete(item)

        # データの挿入
        for row in data:
            self.treeview.insert("", "end", values=row)

前のコードのようにimport_table_data()という関数を定義して、__init__()で呼び出す。

Treeviewクラスのメソッドのinsertでデータ挿入できる。

また、get_children()関数ですでに挿入されたデータを取得し、delete()関数でその要素を消せる。

今のアプリには「既存テーブルのデータ削除」処理は意味がないけど、今後表データを挿入するとき、表データをリセットしたいから書いておきます

なお、入力が面倒なのでデータは10倍してます、、、

ちょっと微調整

今の状態だと表の幅が均一になっているので、幅を調整するために、少しcreate_table()関数を修正する。

class Tables(tk.Frame):

    ...中略...

    def create_table(self):
        # 表の列名
        columns = [
            {"name": "Title", "width": 200},
            {"name": "Description", "width": 300},
            {"name": "Link", "width": 190},
            {"name": "Date", "width": 90},
        ]

        # Treeviewウィジェットを作成
        self.treeview = ttk.Treeview(
            self.master, columns=[col["name"] for col in columns], show="headings"
        )

        # 列名を設定
        for col in columns:
            name = col["name"]
            width = col["width"]
            self.treeview.heading(name, text=name)
            self.treeview.column(name, width=width)

        # スクロールバーを追加
        ...中略...

列に幅の情報を持たせたものとして、columnsを定義し直して修正した。


アプリを起動すると以下のようになる。

第2回 データの挿入までの画面

お~、データが表示されるようになったわ
当たり前だけど、スクロールバーで移動もできるのね

微調整した割にデータが見づらいね

第3回では行を選択して、詳細を表示させるウィジェットを作っていきます ദ്ദി^._.^)