質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.07%

【Tkinter】複数行 値の入力→計算→出力の実装方法について

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 962

Python初心者です。
円面積または円周を計算するアプリを作成しています。

プルダウンから円面積または円周を選択し、左のテキストボックスに半径を入力して、
実行ボタンを押すと右のテキストボックスに計算結果が表示されるというものです。
1回に20行(20個)まとめて計算できるものにしようと考えています。

現在、値の入出力の箇所の実装方法が思いつかず困っております。
どなたか教えてください。よろしくお願いいたします。

現在の入力されているコードは以下のページを参考にして作成しています。
https://teratail.com/questions/235208 (私の過去質問)
http://ja.voidcc.com/question/p-wneapznl-op.html

# -*- coding: utf-8 -*-
from tkinter import *
import tkinter as tk
import tkinter.ttk as ttk

#円面積・計算式
def menseki(self):
    inputNum = int(entry.get())
    menseki = str(inputNum * inputNum * 3.14)
    return menseki

#円周・計算式
def enshu(self):
    inputNum = int(entry.get())
    enshu = str(2 * inputNum * 3.14)
    return enshu

#プルダウンリスト
action = {
    "1.円面積":menseki,
    "2.円周": enshu,
}

#値の入出力
def calculate():
    value = int(entry.get())  
    calc = action.get(combo.get())
    answer.delete(0, tk.END)
    answer.insert(0, calc(value))

#入力値・出力値をクリア
def delete():
    entry.delete(0,tk.END)
    answer.delete(0, tk.END)

#ウインド画面の作成
root = tk.Tk()
root.title("円面積・円周 計算アプリ")
root.geometry("400x400")

def _on_frame_configure(self, event=None):
    canvas.configure(scrollregion=canvas.bbox("all"))

#プルダウンの設定
combo = ttk.Combobox(root, state="readonly",width=26)
combo["values"] = list(action.keys())
combo.place(x=80, y=50)

#フレームの設定
frame =Frame(root, borderwidth=1, relief=SUNKEN,bg="black") 
frame.grid(column=0, row=0, padx=50, pady=100)

#スクロールバーの設定
yscrollbar = Scrollbar(frame) 
yscrollbar.grid(column=1, row=0, sticky=N+S) 

#キャンバスの設定
canvas = Canvas(frame, width=290, height=220,bd=0,yscrollcommand=yscrollbar.set) 
canvas.grid(column=0, row=0, sticky=N+S+E+W) 

#スクロールバーを動かす
yscrollbar.config(command=canvas.yview) 


frame = Frame(canvas, borderwidth=1, relief=SUNKEN) 
canvas.create_window(4,4,window=frame, anchor='nw') 
frame.bind("<Configure>",_on_frame_configure)

#ラベル・テキストボックスの設定
for i in range(1, 21):
    #番号
    label = ttk.Label(frame, text=""+str(i))
    label.grid(column=1, row=i, sticky=W)

    #入力箇所
    entry = ttk.Entry(frame, textvariable="")
    entry.grid(column=2, row=i, sticky=W)

    #計算結果を示す右矢印
    labe2 = ttk.Label(frame, text="⇒") 
    labe2.grid(column=3, row=i, sticky=W)

    #出力箇所
    answer = ttk.Entry(frame, textvariable="")
    answer.grid(column=4, row=i, sticky=W)

# 実行ボタンの設定
button1=tk.Button(root,text="実行",font=("Meiryo UI",8),width=8,height=2,bg="steel blue",fg="white",command=calculate)
button1.place(x=300, y=30)

#クリアボタンの設定
button2=tk.Button(root,text="全クリア",font=("Meiryo UI",8),width=8,height=2,bg="ivory2",fg="black",command=delete)
button2.place(x=300, y=350)

root.mainloop()
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

entryとanswerをリストに保持しておくのがいいと思います。
こんな感じで。

from tkinter import *
import tkinter as tk
import tkinter.ttk as ttk

PI = 3.14


def menseki(r):
    """円面積を計算して返す"""
    return PI * r**2


def enshu(r):
    """円周の長さを計算して返す"""
    return 2 * PI * r


def nop(r):
    pass


# プルダウンリスト
action = {
    "1.円面積": menseki,
    "2.円周": enshu,
}

def calculate():
    """計算"""
    for entry, answer in zip(entries, answers):
        answer.delete(0, tk.END)
        try:
            value = int(entry.get().strip())
            calc = action.get(combo.get(), nop)
            answer.insert(0, calc(value))
        except ValueError:
            pass


def delete():
    """入力値・出力値をクリア"""
    for entry, answer in zip(entries, answers):
        entry.delete(0, tk.END)
        answer.delete(0, tk.END)


# ウインド画面の作成
root = tk.Tk()
root.title("円面積・円周 計算アプリ")
root.geometry("400x400")


def _on_frame_configure(self, event=None):
    canvas.configure(scrollregion=canvas.bbox("all"))


# プルダウンの設定
combo = ttk.Combobox(root, state="readonly", width=26)
combo["values"] = list(action.keys())
combo.place(x=80, y=50)

# フレームの設定
frame = Frame(root, borderwidth=1, relief=SUNKEN, bg="black")
frame.grid(column=0, row=0, padx=50, pady=100)

# スクロールバーの設定
yscrollbar = Scrollbar(frame)
yscrollbar.grid(column=1, row=0, sticky=N+S)

# キャンバスの設定
canvas = Canvas(frame, width=290, height=220, bd=0,
                yscrollcommand=yscrollbar.set)
canvas.grid(column=0, row=0, sticky=N+S+E+W)

# スクロールバーを動かす
yscrollbar.config(command=canvas.yview)


frame = Frame(canvas, borderwidth=1, relief=SUNKEN)
canvas.create_window(4, 4, window=frame, anchor='nw')
frame.bind("<Configure>", _on_frame_configure)

# ラベル・テキストボックスの設定
entries = []
answers = []
for i in range(1, 21):
    # 番号
    label = ttk.Label(frame, text=""+str(i))
    label.grid(column=1, row=i, sticky=W)

    # 入力箇所
    entry = ttk.Entry(frame, textvariable="")
    entry.grid(column=2, row=i, sticky=W)
    entries.append(entry)

    # 計算結果を示す右矢印
    labe2 = ttk.Label(frame, text="⇒")
    labe2.grid(column=3, row=i, sticky=W)

    # 出力箇所
    answer = ttk.Entry(frame, textvariable="")
    answer.grid(column=4, row=i, sticky=W)
    answers.append(answer)

# 実行ボタンの設定
button1 = tk.Button(root, text="実行", font=("Meiryo UI", 8), width=8,
                    height=2, bg="steel blue", fg="white", command=calculate)
button1.place(x=300, y=30)

# クリアボタンの設定
button2 = tk.Button(root, text="全クリア", font=("Meiryo UI", 8),
                    width=8, height=2, bg="ivory2", fg="black", command=delete)
button2.place(x=300, y=350)

root.mainloop()

もし、クラス定義(ユーザ定義データ型)を理解できるなら、entry と answer をまとめたクラスにするのもいい手だと思います。

from tkinter import *
import tkinter as tk
import tkinter.ttk as ttk

PI = 3.14


def menseki(r):
    """円面積を計算して返す"""
    return PI * r**2


def enshu(r):
    """円周の長さを計算して返す"""
    return 2 * PI * r


# プルダウンリスト
action = {
    "1.円面積": menseki,
    "2.円周": enshu,
}


class CaluculateVar:

    def __init__(self):
        self.entry = tk.StringVar()
        self.answer = tk.StringVar()

    def calculate(self, formura):
        try:
            self.answer.set(formura(int(self.entry.get())))
        except ValueError:
            self.answer.set("")

    def clear(self):
        self.entry.set("")
        self.answer.set("")


def calculate():
    """一括計算"""
    formura = action.get(combo.get())
    if not formura:
        return
    for variable in variables:
        variable.calculate(formura)


def clear():
    """入力値・出力値をクリア"""
    for variable in variables:
        variable.clear()


# ウインド画面の作成
root = tk.Tk()
root.title("円面積・円周 計算アプリ")
root.geometry("400x400")


def _on_frame_configure(self, event=None):
    canvas.configure(scrollregion=canvas.bbox("all"))


# プルダウンの設定
combo = ttk.Combobox(root, state="readonly", width=26)
combo["values"] = list(action.keys())
combo.place(x=80, y=50)

# フレームの設定
frame = Frame(root, borderwidth=1, relief=SUNKEN, bg="black")
frame.grid(column=0, row=0, padx=50, pady=100)

# スクロールバーの設定
yscrollbar = Scrollbar(frame)
yscrollbar.grid(column=1, row=0, sticky=N+S)

# キャンバスの設定
canvas = Canvas(frame, width=290, height=220, bd=0,
                yscrollcommand=yscrollbar.set)
canvas.grid(column=0, row=0, sticky=N+S+E+W)

# スクロールバーを動かす
yscrollbar.config(command=canvas.yview)


frame = Frame(canvas, borderwidth=1, relief=SUNKEN)
canvas.create_window(4, 4, window=frame, anchor='nw')
frame.bind("<Configure>", _on_frame_configure)

# ラベル・テキストボックスの設定
variables = [CaluculateVar() for _ in range(20)]
for i, variable in enumerate(variables, 1):
    # 番号
    label = ttk.Label(frame, text=str(i))
    label.grid(column=1, row=i, sticky=W)

    # 入力箇所
    entry = ttk.Entry(frame, textvariable=variable.entry)
    entry.grid(column=2, row=i, sticky=W)

    # 計算結果を示す右矢印
    labe2 = ttk.Label(frame, text="⇒")
    labe2.grid(column=3, row=i, sticky=W)

    # 出力箇所
    answer = ttk.Entry(frame, textvariable=variable.answer)
    answer.grid(column=4, row=i, sticky=W)

# 実行ボタンの設定
button1 = tk.Button(root, text="実行", font=("Meiryo UI", 8), width=8,
                    height=2, bg="steel blue", fg="white", command=calculate)
button1.place(x=300, y=30)

# クリアボタンの設定
button2 = tk.Button(root, text="全クリア", font=("Meiryo UI", 8),
                    width=8, height=2, bg="ivory2", fg="black", command=clear)
button2.place(x=300, y=350)

root.mainloop()

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.07%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る