<初心者向け>Pythonで計算機アプリを作ってみた

## 1. はじめに

Pythonの tkinter を使って簡単な 計算機アプリ を作成しました。Linux環境で開発し、手順や発生したエラーとその解決策 をまとめます。

・開発環境: Ubuntu 22.04
・使用エディタ: VScode
・使用ライブラリ: tkinter使用ライブラリ

## 2. 計算機アプリの作成
#### 2.1 プロジェクトの構成

```
calc_app/
├── src/
│   ├── main.py       # メインのエントリーポイント
│   ├── gui.py        # GUI の処理
│   ├── logic.py      # 計算処理のロジック
└── README.md
```

#### 2.2 コードの概要
**<エントリーポイント>**

```
from gui import CalculatorGUI

if __name__ == "__main__":
    app = CalculatorGUI()
    app.run()
```
**＜GUI処理＞**

```
import tkinter as tk
from logic import CalculatorLogic

class CalculatorGUI:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("シンプル計算機")
        
        self.entry = tk.Entry(self.root, width=20, font=("Arial", 18), justify="right")
        self.entry.grid(row=0, column=0, columnspan=4)
        
        self.logic = CalculatorLogic(self.entry)
        
        button_params = {"font": ("Arial", 14), "width": 5, "height": 2}
        buttons = [
            ("7", 1, 0), ("8", 1, 1), ("9", 1, 2), ("/", 1, 3),
            ("4", 2, 0), ("5", 2, 1), ("6", 2, 2), ("*", 2, 3),
            ("1", 3, 0), ("2", 3, 1), ("3", 3, 2), ("-", 3, 3),
            ("0", 4, 0), ("C", 4, 1), ("=", 4, 2), ("+", 4, 3)
        ]
        
        for (text, row, col) in buttons:
            if text == "=":
                btn = tk.Button(self.root, text=text, command=self.logic.calculate, **button_params)
            elif text == "C":
                btn = tk.Button(self.root, text=text, command=self.logic.clear, **button_params)
            else:
                btn = tk.Button(self.root, text=text, command=lambda t=text: self.logic.on_button_click(t), **button_params)
            btn.grid(row=row, column=col, padx=5, pady=5)
    
    def run(self):
        self.root.mainloop()
```

**<計算機>**

```
import tkinter as tk

class CalculatorLogic:
    def __init__(self, entry_widget):
        self.entry = entry_widget
    
    def on_button_click(self, value):
        self.entry.insert(tk.END, value)
    
    def calculate(self):
        try:
            result = eval(self.entry.get())
            self.entry.delete(0, tk.END)
            self.entry.insert(tk.END, str(result))
        except:
            self.entry.delete(0, tk.END)
            self.entry.insert(tk.END, "エラー")
    
    def clear(self):
        self.entry.delete(0, tk.END)
```

## 3. 実行時のエラーと解決策
#### 3.1 Error:tkinter
**エラー内容**
```
ModuleNotFoundError: No module named 'tkinter'
```
**解決策**
Linux の場合、tkinter は python3-tk をインストールする必要があります。
```
sudo apt install python3-tk
```
#### 3.2 Error:DISPLAY
**エラー内容**
```
_tkinter.TclError: no display name and no $DISPLAY environment variable
```
**解決策**
GUI を使うには DISPLAY を設定する必要があります。
```
export DISPLAY=:0
```
また、X11転送を有効にするには、SSHログイン時に -X または -Y を付けます。
```
ssh -Y username@server
```
WSL や Docker では、仮想ディスプレイ xvfb を使う方法もあります。
```
sudo apt install xvfb
xvfb-run python3 main.py
```

## 実行
```
# main.pyが格納されているPath上で実行
# 実行ファイルに権限を付けてください -> sudo chmod -R +x ./*
python3 main.py
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/825bfb63-6a84-4205-9465-86fec831ce61.png)


ゆっくり調べながら作っても1時間ほどで作れるかと思います。
以上、備忘録でした。