PythonとTkinterで作る！おしゃれでポップなタブGUI

## はじめに

こんにちは！今回は、PythonとTkinterを使って、おしゃれでポップなタブ付きGUIアプリケーションを作成する方法をご紹介します。単調になりがちなGUIアプリに、カラフルな要素とアニメーション効果を加えて、より魅力的なインターフェイスを作り上げましょう。

## 完成イメージ

このコードを実行すると、以下のような特徴を持つGUIアプリケーションが作成されます：

- カラフルなタブデザイン
- 3つのユニークなタブコンテンツ
- タブ切り替え時のスムーズなアニメーション効果
- ウィンドウサイズに応じた responsive なレイアウト

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/445cba05-7713-f86f-595b-0b7c927df50a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/093c3669-a8fc-a5f4-885d-14971483200f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/dbcfc84e-252e-ce4d-a4c5-478208d5c590.png)

## コード全体

まずは、完全なコードを見てみましょう。その後、各部分の詳細な説明に移ります。

```python
import tkinter as tk
from tkinter import ttk
import random

def random_color():
    return "#{:02x}{:02x}{:02x}".format(random.randint(100, 255), random.randint(100, 255), random.randint(100, 255))

def tab_changed(event):
    tab = event.widget.select()
    tab_id = event.widget.index(tab)
    
    for widget in tabs[tab_id].winfo_children():
        widget.place(relx=1.0, rely=0.5, anchor="e")
        widget.after(10, lambda w=widget: smooth_move(w, 0, 30))

def smooth_move(widget, pos, steps):
    if pos < steps:
        widget.place(relx=1.0 - (pos / steps), rely=0.5, anchor="e")
        widget.after(10, lambda: smooth_move(widget, pos + 1, steps))

root = tk.Tk()
root.title("ポップなタブウィンドウ")
root.geometry("600x400")

style = ttk.Style()
style.theme_create("colorful", parent="alt", settings={
    "TNotebook": {"configure": {"tabmargins": [2, 5, 2, 0], "background": "#F0F0F0"}},
    "TNotebook.Tab": {
        "configure": {"padding": [20, 10], "font": ('Comic Sans MS', '12', 'bold')},
        "map": {"background": [("selected", random_color())],
                "foreground": [("selected", "#FFFFFF")]}
    }
})
style.theme_use("colorful")

notebook = ttk.Notebook(root)

tab_titles = ["楽しい！", "わくわく", "にこにこ"]
tabs = []

for title in tab_titles:
    tab = ttk.Frame(notebook)
    tabs.append(tab)
    notebook.add(tab, text=title)

# 楽しい！タブのコンテンツ
frame1 = tk.Frame(tabs[0], bg=random_color())
label1 = tk.Label(frame1, text="Welcome to Fun Zone!", font=("Comic Sans MS", 24, "bold"), fg="white", bg=frame1["bg"])
label1.pack(pady=20, padx=20)
button1 = tk.Button(frame1, text="Click for Fun!", bg=random_color(), fg="white", font=("Arial", 16, "bold"))
button1.pack(pady=20)
frame1.place(relx=0.5, rely=0.5, anchor="center")

# わくわくタブのコンテンツ
frame2 = tk.Frame(tabs[1])
canvas = tk.Canvas(frame2, width=500, height=300, bg='white')
canvas.pack(pady=10)
for _ in range(30):
    x, y = random.randint(0, 500), random.randint(0, 300)
    size = random.randint(20, 50)
    canvas.create_oval(x, y, x+size, y+size, fill=random_color(), outline="")
frame2.place(relx=0.5, rely=0.5, anchor="center")

# にこにこタブのコンテンツ
frame3 = tk.Frame(tabs[2], bg=random_color())
happy_faces = ["😊", "😄", "😃", "😁", "😆"]
label3 = tk.Label(frame3, text=" ".join(happy_faces), font=("Segoe UI Emoji", 48), bg=frame3["bg"])
label3.pack(pady=20)
scale = tk.Scale(frame3, from_=1, to=10, orient="horizontal", label="幸せ度", length=300, font=("Arial", 14), troughcolor=random_color(), bg=frame3["bg"])
scale.pack(pady=20)
frame3.place(relx=0.5, rely=0.5, anchor="center")

# フレームのサイズを調整して中央揃えを改善
def adjust_frames(event):
    for frame in [frame1, frame2, frame3]:
        frame.update_idletasks()  # フレームのサイズを更新
        frame_width = frame.winfo_width()
        frame_height = frame.winfo_height()
        frame.place(relx=0.5, rely=0.5, anchor="center", width=frame_width, height=frame_height)

root.bind("<Configure>", adjust_frames)

notebook.pack(expand=True, fill="both")
notebook.bind("<<NotebookTabChanged>>", tab_changed)

root.mainloop()
```

## コードの詳細説明

### 1. 基本設定とスタイリング

```python
style = ttk.Style()
style.theme_create("colorful", parent="alt", settings={
    "TNotebook": {"configure": {"tabmargins": [2, 5, 2, 0], "background": "#F0F0F0"}},
    "TNotebook.Tab": {
        "configure": {"padding": [20, 10], "font": ('Comic Sans MS', '12', 'bold')},
        "map": {"background": [("selected", random_color())],
                "foreground": [("selected", "#FFFFFF")]}
    }
})
style.theme_use("colorful")
```

このセクションでは、タブのスタイルをカスタマイズしています。ランダムな背景色、太字のフォント、適切なパディングを設定し、視覚的に魅力的なタブを作成しています。

### 2. タブの作成

```python
tab_titles = ["楽しい！", "わくわく", "にこにこ"]
tabs = []

for title in tab_titles:
    tab = ttk.Frame(notebook)
    tabs.append(tab)
    notebook.add(tab, text=title)
```

3つのタブを作成し、それぞれに面白いタイトルを付けています。

### 3. タブコンテンツの作成

各タブには異なるコンテンツを配置しています：

- 「楽しい！」タブ：カラフルなラベルとボタン
- 「わくわく」タブ：ランダムな色の円が描かれたキャンバス
- 「にこにこ」タブ：絵文字と「幸せ度」スケール

### 4. アニメーション効果

```python
def tab_changed(event):
    tab = event.widget.select()
    tab_id = event.widget.index(tab)
    
    for widget in tabs[tab_id].winfo_children():
        widget.place(relx=1.0, rely=0.5, anchor="e")
        widget.after(10, lambda w=widget: smooth_move(w, 0, 30))

def smooth_move(widget, pos, steps):
    if pos < steps:
        widget.place(relx=1.0 - (pos / steps), rely=0.5, anchor="e")
        widget.after(10, lambda: smooth_move(widget, pos + 1, steps))
```

これらの関数により、タブ切り替え時にコンテンツが右から左へスムーズに移動するアニメーション効果を実現しています。

### 5. レスポンシブレイアウト

```python
def adjust_frames(event):
    for frame in [frame1, frame2, frame3]:
        frame.update_idletasks()  # フレームのサイズを更新
        frame_width = frame.winfo_width()
        frame_height = frame.winfo_height()
        frame.place(relx=0.5, rely=0.5, anchor="center", width=frame_width, height=frame_height)

root.bind("<Configure>", adjust_frames)
```

この関数により、ウィンドウサイズが変更されても各タブのコンテンツが常に中央に配置されるようになります。

## まとめ

このコードを使用することで、以下の要素を持つ魅力的なGUIアプリケーションを作成できます：

1. カラフルでポップなデザイン
2. タブ切り替え時のスムーズなアニメーション
3. レスポンシブなレイアウト
4. 各タブに特徴的なコンテンツ

このベースを使って、さらに機能を追加したり、デザインをカスタマイズしたりすることで、より魅力的なアプリケーションを作ることができます。

Pythonの`tkinter`ライブラリは非常に柔軟で、少し工夫を加えるだけで、このようなおしゃれなGUIを簡単に作成できます。ぜひ、自分のプロジェクトにも活用してみてください！

## 発展のアイデア

1. 色のテーマを選択できる機能を追加する
2. タブの数を動的に増減できるようにする
3. 各タブに実際の機能（例：簡単なゲーム、計算機、メモ帳など）を実装する
4. アニメーション効果のオン/オフを切り替えられるようにする

ぜひ、これらのアイデアを試してみて、さらに素晴らしいGUIアプリケーションを作ってみてください！