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

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

ただいまの
回答率

90.47%

  • Python 3.x

    10245questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

  • Tkinter

    282questions

    Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

  • INSERT

    55questions

    INSERTとは、行を追加する、コンピュータのデータベース言語SQLにおけるデータ操作言語(DML)ステートメントの1つである

[Python3]tkinterで別クラスへ値をinsertする方法

解決済

回答 1

投稿

  • 評価
  • クリップ 2
  • VIEW 2,017

 前提・実現したいこと

Python3.6で時差を計算するシステムを作っています。
コンボボックスからエントリーボックスへ値を渡す為の機能を実装しているのですが、
insertを使って、別のクラスの関数に入っているエントリーボックスへ値を出力したいと考えています。

イメージ説明

#coding: utf-8

import tkinter as tk
from tkinter import ttk
from datetime import datetime
import csv


class Data:

    def data_input(self):
        # リスト型
        t = []
        v = []
        key = ['Country', 'UTC', 'Summer']
        country_info = {}

        # CSVファイルを開く
        with open("data/csv/utc_original.csv", encoding="UTF-8") as f:
            reader = csv.reader(f)
            header = next(reader)
            # 1行ごとにリスト型に格納
            for row in reader:
                row[2] = (float(row[2]))
                if row[3] == 'True':
                    row[3] = True
                elif row[3] == 'False':
                    row[3] = False
                t.append(row)

        # 首都のみリストに移動
        for i in range(len(t)):
            v.append(t[i][0])
            t[i].remove(t[i][0])

        # keyリストからキーを取得しながら、情報を格納して、首都をキーに指定
        for i in range(len(t)):
            dic = dict(zip(key, t[i]))
            country_info[v[i]] = dic

        return country_info

    def data_day(self):
        a = datetime.now().strftime("%H")
        var = tk.StringVar(root)
        var.set(a)

        return var



class Cmb(ttk.Combobox):
    # --- クラス Cmb コマンドボックスの値 ---
    def __init__(self, master, dictionary, *args, **kw):
        ttk.Combobox.__init__(self, master, values = sorted(list(dictionary.keys())), state = 'readonly',width=30, *args, **kw)
        self.dictionary = dictionary
        self.bind('<<ComboboxSelected>>', self.selected)

    def value(self):
        return self.dictionary[self.get()]

    def selected(self, event):
        print(self.value()['UTC'])
        a = self.value()['UTC']

        ここから a の値をClassのApplication内の、関数create_entry内のety0 へ渡したい







class Application(tk.Frame):

    def __init__(self, master=None):
        super().__init__(master)
        master.title("時差計算アプリ")
        master.resizable(0, 0)
        master.geometry("480x200")
        master.grid_rowconfigure(1, weight=1)
        master.grid_columnconfigure(0, weight=1)
        self.pack()

        self.header = tk.Frame(self.master, bg='#999999', width=500, height=10, pady=3)
        self.center = tk.Frame(self.master, bg='#dddddd', width=500, height=10, pady=3)
        self.footer0 = tk.Frame(self.master, bg='#dddddd', width=500, height=10, pady=3)
        self.footer1 = tk.Frame(self.master, bg='#dddddd', width=500, height=10, pady=3)
        self.create_layout()

        self.head_left = tk.Frame(self.header, bg='#999999', width=100, height=10, padx=3, pady=3)
        self.head_mid0 = tk.Frame(self.header, bg='#999999', width=200, height=10, padx=3, pady=3)
        self.head_mid1 = tk.Frame(self.header, bg='#999999', width=100, height=10, padx=3, pady=3)
        self.head_right = tk.Frame(self.header, bg='#999999', width=100, height=10, padx=3, pady=3)
        self.create_header()

        self.cnt_left = tk.Frame(self.center, bg='#dddddd', width=100, height=10, padx=3, pady=3)
        self.cnt_mid0 = tk.Frame(self.center, bg='#dddddd', width=200, height=10, padx=3, pady=3)
        self.cnt_mid1 = tk.Frame(self.center, bg='#dddddd', width=50, height=10, padx=0, pady=0)
        self.cnt_mid2 = tk.Frame(self.center, bg='#dddddd', width=50, height=10, padx=3, pady=3)
        self.cnt_right = tk.Frame(self.center, bg='#dddddd', width=100, height=10, padx=3, pady=3)
        self.create_center()

        self.ftr_left = tk.Frame(self.footer0, bg='#dddddd', width=70, height=10, padx=3, pady=3)
        self.ftr_mid0 = tk.Frame(self.footer0, bg='#dddddd', width=70, height=10, padx=3, pady=3)
        self.ftr_mid1 = tk.Frame(self.footer0, bg='#dddddd', width=70, height=10, padx=3, pady=3)
        self.ftr_mid2 = tk.Frame(self.footer0, bg='#dddddd', width=70, height=10, padx=3, pady=3)
        self.ftr_mid3 = tk.Frame(self.footer0, bg='#dddddd', width=70, height=10, padx=3, pady=3)
        self.ftr_right = tk.Frame(self.footer0, bg='#dddddd', width=10, height=10, padx=3, pady=3)
        self.create_footer()

        self.create_label()
        self.create_enter()
        self.create_checkbox()
        self.create_button()
        self.create_spin()
        self.create_cmb()
        self.create_pack()


    def create_layout(self):
        # --- コンテナ設計 ---
        self.header.grid(row=0, sticky="ew")
        self.center.grid(row=1, sticky="nsew")
        self.footer0.grid(row=2, sticky="ew")
        self.footer1.grid(row=3, sticky="ew")

    def create_header(self):
        # --- headerの詳細設計 ---
        self.header.grid_rowconfigure(0, weight=1)
        self.header.grid_columnconfigure(1, weight=1)

        self.head_left.grid(row=0, column=0, sticky="ns")
        self.head_mid0.grid(row=0, column=1, sticky="nsew")
        self.head_mid1.grid(row=0, column=2, sticky="nsew")
        self.head_right.grid(row=0, column=3, sticky="ns")

    def create_center(self):
        # --- centerの詳細設計 ---
        self.center.grid_rowconfigure(0, weight=1)
        self.center.grid_columnconfigure(1, weight=1)

        self.cnt_left.grid(row=0, column=0, sticky="ns")
        self.cnt_mid0.grid(row=0, column=1, sticky="nsew")
        self.cnt_mid1.grid(row=0, column=2, sticky="nsew")
        self.cnt_mid2.grid(row=0, column=3, sticky="nsew")
        self.cnt_right.grid(row=0, column=4, sticky="ns")


    def create_footer(self):
        # -- footer0の詳細 ---
        self.footer0.grid_rowconfigure(0, weight=1)
        self.footer0.grid_columnconfigure(1, weight=1)

        self.ftr_left.grid(row=0, column=0, sticky="ns")
        self.ftr_mid0.grid(row=0, column=1, sticky="nsew")
        self.ftr_mid1.grid(row=0, column=2, sticky="nsew")
        self.ftr_mid2.grid(row=0, column=3, sticky="nsew")
        self.ftr_mid3.grid(row=0, column=4, sticky="nsew")
        self.ftr_right.grid(row=0, column=5, sticky="ns")

    def create_pack(self):

        self.header.pack()
        self.center.pack()
        self.footer0.pack()
        self.footer1.pack()

    def create_label(self):
        # --- テキストラベル ---
        lbl0 = tk.Label(self.head_left, text="CSV version", fg='blue', bg='#999999', padx=5, pady=5)
        lbl1 = tk.Label(self.cnt_left, text="City1:", bg='#dddddd', padx=5, pady=1)
        lbl2 = tk.Label(self.cnt_left, text="City2:", bg='#dddddd', padx=5, pady=1)
        lbl3 = tk.Label(self.cnt_mid2, text="UTC:", bg='#dddddd', padx=5, pady=1)
        lbl4 = tk.Label(self.cnt_mid2, text="UTC:", bg='#dddddd', padx=5, pady=1)
        lbl5 = tk.Label(self.ftr_left, text="現在時刻:", bg='#dddddd', padx=5, pady=1)
        lbl6 = tk.Label(self.ftr_mid0, text="〇", bg='#dddddd', padx=5, pady=1)
        lbl7 = tk.Label(self.ftr_mid1, text="C1:", bg='#dddddd', padx=5, pady=1)
        lbl8 = tk.Label(self.ftr_mid2, text="C2:", bg='#dddddd', padx=5, pady=1)

        lbl0.grid(row=0, column=0)
        lbl1.grid(row=0)
        lbl2.grid(row=1)
        lbl3.grid(row=0, column=0)
        lbl4.grid(row=1, column=0)
        lbl5.pack()
        lbl6.pack()
        lbl7.pack(side='top')
        lbl8.pack(side='top')

        return lbl0, lbl1, lbl2, lbl3, lbl4, lbl5, lbl6, lbl7, lbl8

    def create_enter(self):
        # --- テキストボックス ---
        ety0 = tk.Entry(self.cnt_right, width=10)
        ety1 = tk.Entry(self.cnt_right, width=10)
        ety2 = tk.Entry(self.ftr_left, width=10)
        ety3 = tk.Entry(self.ftr_mid0, width=10)
        ety4 = tk.Entry(self.ftr_mid2, width=10)

        ety0.pack()
        ety1.pack()
        ety2.pack()
        ety3.pack()
        ety4.pack(side='top')

        return ety0, ety1, ety2, ety3, ety4

    def create_checkbox(self):
        # --- チェックボックス ---
        chk2 = tk.Checkbutton(self.cnt_mid1, text='DST', bg='#dddddd').pack()
        chk3 = tk.Checkbutton(self.cnt_mid1, text='DST', bg='#dddddd').pack()

        return chk2, chk3

    def create_button(self):
        btn0 = tk.Button(self.head_right, text='計算')
        btn1 = tk.Button(self.head_right, text='クリア', width=10, bg='#dddddd')
        btn2 = tk.Button(self.footer1, text='Yesterday', bg='#dddddd', width=10)
        btn3 = tk.Button(self.footer1, text='Today', bg='#dddddd', width=10)
        btn4 = tk.Button(self.footer1, text='Tomorrow', bg='#dddddd', width=10)

        btn0.pack(side='right')
        btn1.pack(side='right')
        btn2.pack(side='right')
        btn3.pack(side='right')
        btn4.pack(side='right')

        return btn0, btn1, btn2, btn3, btn4

    def create_spin(self):
        i = Data()
        spn1 = tk.Spinbox(self.ftr_mid1, from_=1, to=24, textvariable=i.data_day(), width=10)

        spn1.pack()

        return spn1

    def create_cmb(self):
        i = Data()
        cmb1 = Cmb(self.cnt_mid0,i.data_input())
        cmb2 = ttk.Combobox(self.cnt_mid0)
        cmb1.set('都市名を選択')
        cmb2.set('都市名を選択')

        cmb1.pack()
        cmb2.pack()

        return cmb1, cmb2



if __name__ == '__main__':
    root = tk.Tk()
    app = Application(master=root)
    app.mainloop()
国,都市,UTC,DST
ハワイ,アメリカ,-10,False
ロサンゼルス,アメリカ,-8,True
デンバー,アメリカ,-7,True
シカゴ,アメリカ,-6,True
ニューヨーク,アメリカ,-5,True
ブエノスアイレス,アルゼンチン,-3,True
キト,エクアドル,-5,False
バンクーバー ,カナダ,-8,True
バンフ,カナダ,-7, True

宜しくお願い致します。

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

以下のような手順で実装できるかと思います。

(1)Cmbクラスから他のクラスに対してコンボボックスの選択変更を通知する仕組みを作る

とりあえずであれば、Cmbクラスのコンストラクタ引数に callback を追加(インスタンス変数に追加)し、選択変更時にcallbackに格納された関数をコールするように変更するのが簡単かと思います

class Cmb(ttk.Combobox):
    def __init__(self, master, dictionary, callback, *args, **kw):
        ttk.Combobox.__init__(self, master, values = sorted(list(dictionary.keys())), state = 'readonly',width=30, *args, **kw)
        self.dictionary = dictionary
        self.bind('<<ComboboxSelected>>', self.selected)
        self.callback = callback # <--- 追加

    def value(self):
        return self.dictionary[self.get()]

    def selected(self, event):
        a = self.value()['UTC']
        self.callback(a) # <--- 追加(callbackに格納された関数をコールする)

(2)Applicationクラスにて(1)の変更に対応して、コンボボックスの選択変更を受信できるようにする

class Application(tk.Frame):
    ##### 略 #####

    def create_cmb(self):
        i = Data()
        cmb1 = Cmb(self.cnt_mid0,i.data_input(), self.change_cmb_value) # <--- (1)に合わせて修正
        cmb2 = ttk.Combobox(self.cnt_mid0)
        cmb1.set('都市名を選択')
        cmb2.set('都市名を選択')

        cmb1.pack()
        cmb2.pack()

        return cmb1, cmb2

    # 以下のインスタンスメソッドを追加
    # コンボボックスの値が変更されったときにコールされる
    def change_cmb_value(self, val):
        print(val)

(3)ety0~ety4 を Applicationクラスのインスタンス変数にする

class Application(tk.Frame):
    def __init__(self, master=None):
        ### 略 ###
        # self.create_enter() の行を以下のようにして、ent0~4をインスタンス変数に格納
        self.enter_objects = self.create_enter()
        ### 略 ###

(4)(2)で追加したインスタンスメソッドに、ety0 の値を更新する処理を実装

    def change_cmb_value(self, val):
        print(val)
        self.enter_objects[0].delete(0,tk.END)
        self.enter_objects[0].insert(0,'{}'.format(val))

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/02/01 11:43

    magichanさま。こんにちは、誠にありがとうございます!!callback変数というのがあるのですね。勉強になります。記述してくださったコードをじっくり理解を進めようと思います。m(_ _)m

    キャンセル

  • 2018/02/01 12:18

    > callback変数というのがあるのですね
    いや・・・ちょっと勘違いがあるような気がします。
    "callback" というのは、「私が勝手に決めた」単なる変数名です。この変数にはCmbクラスのコンストラクタの第3引数の値がそのまま格納されます。
    で、『このcallback変数(インスタンス変数)に「コールバック先の関数」を格納しておいて、コンボボックスの選択が変更されたときに、その変数に格納された「コールバック先の関数」をコールするようにする』 というのが(1)の修正になります。
    更に説明を追加すると『Cmbクラスのコンストラクタの第3引数にて Applicationクラスの change_cmb_value() メソッドを渡すようにする』というのが(2)の修正になります。
    とりあえずは、この部分は(1)(2)の実装を行うことで動作確認ができますので、動作を確認しながら理解を深めていただけたらと思います。

    キャンセル

  • 2018/02/23 09:41

    magichan さま。 おはようございます。ご無沙汰しております。 ご連絡が遅くなりました。やっとこさ理解できました。おかげさまで、時差計算アプリができました!教えてくださった方法で、衝突のテストも同様の方法で格納できました!ありがとうございます。m(_ _)m

    キャンセル

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

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

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

  • Python 3.x

    10245questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

  • Tkinter

    282questions

    Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

  • INSERT

    55questions

    INSERTとは、行を追加する、コンピュータのデータベース言語SQLにおけるデータ操作言語(DML)ステートメントの1つである