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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Tkinter

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1951閲覧

Tkinterで画面遷移後のテキストボックスに遷移前のテキストボックスの値を自動入力したい

able

総合スコア7

Tkinter

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2020/10/27 15:01

編集2020/10/27 15:10

前提・実現したいこと

 現在、menu.pyからA.py、B.pyを読み出し、画面遷移を行うものを作っています。
記載するコードは単純化したものですが、Aフレームから「Bに入力」ボタンを押し、Bフレームに遷移した時、Aフレームのテキストボックスの値がBフレームのテキストボックスに挿入され、Bフレームの「表示」ボタンが押された状態にしたいのですが、どのようにすれば良いかわからず困っています。
当方、プログラミング初心者なため、どのようなコードにすれば良いかわかりやすくご教授いただけると幸いです。
よろしくお願い致します。

該当のソースコード

menu.py

1#menu.py 2import tkinter as tk 3from tkinter import ttk 4from A import AApp 5from B import BApp 6 7 8class FrameBase(tk.Tk): 9 def __init__(self): 10 tk.Tk.__init__(self) 11 self.frame = MenuFrame(self) 12 self.frame.pack(expand=True, fill="both") 13 14 def change(self, frame): 15 self.frame.pack_forget() 16 self.frame = frame(self) 17 self.frame.pack(expand=True, fill="both") 18 19 def backToMenu(self): 20 self.frame.pack_forget() 21 self.frame = MenuFrame(self) 22 self.frame.pack(expand=True, fill="both") 23 24 def gotoB(self): 25 self.frame.pack_forget() 26 self.frame = BApp(self) 27 self.frame.pack(expand=True, fill="both") 28 29class MenuFrame(tk.Frame): 30 def __init__(self, menu=None, **kwargs): 31 tk.Frame.__init__(self, menu, **kwargs) 32 menu.title("メニュー画面") 33 menu.geometry("100x100") 34 self.grid(column=0, row=0, sticky=tk.NSEW) 35 36 self.Applist =[ [AApp, "A"], [BApp, "B"] ] 37 38 for i in range(2): 39 btn = tk.Button(master=self, wraplength=50, justify=tk.LEFT,text=self.Applist[i][1], 40 command=self.gotoApp(i)) 41 btn.grid(column=i, row=1, padx=10, pady=10, sticky=tk.NSEW) 42 43 44 def gotoApp(self,i): 45 return lambda :self.master.change(self.Applist[i][0]) 46 47def main(): 48 app = FrameBase() 49 app.mainloop() 50 51 52if __name__ == "__main__": 53 main()

A.py

1#A.py 2import tkinter as tk 3from B import BApp 4 5class AApp (tk.Frame): 6 def __init__(self, A=None, **kwargs): 7 tk.Frame.__init__(self,A, **kwargs) 8 9 def btnA2_click(): 10 self.master.gotoB()#ここから先が不明 11 BApp.TextBoxB.insert(tk.END,TextBoxA.get()) 12 BApp.btnB2_click() 13 14 A.title("A") 15 A.geometry("300x300") 16 17 btnA1 = tk.Button(master=self, wraplength=50, justify=tk.LEFT,text='メニュー', 18 command=self.master.backToMenu) 19 btnA1.grid(column=1, row=1, padx=10, pady=10, sticky=tk.NSEW) 20 21 btnA2 = tk.Button(master=self, wraplength=50, justify=tk.LEFT,text='Bに入力', 22 command=btnA2_click) 23 btnA2.grid(column=2, row=1, padx=10, pady=10, sticky=tk.NSEW) 24 25 TextBoxA = tk.Entry(master=self,state='normal', width=14,justify=tk.CENTER) 26 TextBoxA.grid(column=1, row=2, padx=10, pady=10, sticky=tk.NSEW)

B.py

1#B.py 2import tkinter as tk 3 4class BApp (tk.Frame): 5 def __init__(self, B=None, **kwargs): 6 tk.Frame.__init__(self,B, **kwargs) 7 8 def btnB2_click(): 9 label.config(text=TextBoxB.get()) 10 11 B.title("B") 12 B.geometry("200x200") 13 14 btnB1 = tk.Button(master=self, wraplength=50, justify=tk.LEFT,text='メニュー', 15 command=self.master.backToMenu) 16 btnB1.grid(column=1, row=1, padx=10, pady=10, sticky=tk.NSEW) 17 18 btnB2 = tk.Button(master=self, wraplength=50, justify=tk.LEFT,text='表示', 19 command= btnB2_click) 20 btnB2.grid(column=2, row=1, padx=10, pady=10, sticky=tk.NSEW) 21 22 TextBoxB = tk.Entry(master=self,state='normal', width=14,justify=tk.CENTER) 23 TextBoxB.grid(column=1, row=2, padx=10, pady=10, sticky=tk.NSEW) 24 25 label = tk.Label(master=self, text="") 26 label.grid(column=1, row=3, padx=10, pady=10, sticky=tk.NSEW) 27

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Aフレームから「Bに入力」ボタンを押し、Bフレームに遷移した時、
Aフレームのテキストボックスの値がBフレームのテキストボックスに挿入され、
Bフレームの「表示」ボタンが押された状態にしたい

コードの問題点

python

1def btnA2_click(): 2 self.master.gotoB()#ここから先が不明 3 BApp.TextBoxB.insert(tk.END,TextBoxA.get()) 4 BApp.btnB2_click()
  • BApp はクラスです。

 実際のテキストボックスを操作するには、
BAppを呼び出して作られたインスタンスの方を参照する必要があります。

  • TextBoxB, btnB2_click はローカル変数の為、外部からは参照できません。

 インスタンス変数やメソッドにして、外部からアクセス可能にしてください。

  • gotoB() 後の TextBoxA.get() 呼び出しについて、

 TextBoxA の値は予め変数に確保してから、gotoB を呼び出した方が良いです。(理由は後で説明)

python

1def btnA2_click(): 2 text = TextBoxA.get() 3 self.master.gotoB() 4 self.master.frame.TextBoxB.insert(tk.END, text) 5 self.master.frame.btnB2_click()

B.py 側の変更点

python

1self.TextBoxB = TextBoxB 2self.btnB2_click = btnB2_click

画面遷移の方法について

画面遷移を続けていると使用メモリが増大し続ける問題があります。
問題になるのは、数百回規模で画面遷移を行った場合なので、
問題を再現するのは難しいのですが、現状のコードはこの問題に依存しているため
早めに修正しておいた方が良いです。

画面遷移の手段は主に2通りあり

  • 予めフレームを作成しておき表示・非表示を切り替える方法
  • ページ遷移の度にフレームを破棄、新しいフレームを作る方法

ですが、現状のコードでは

  • ページ遷移の度に、現在のフレームを非表示にし、新しいフレームを生成

非表示にしただけでは破棄されないので、
新しいフレームが増え続けています。

確認手段

python

1class AApp (tk.Frame): 2 def __init__(self, A=None, **kwargs): 3 tk.Frame.__init__(self,A, **kwargs) 4 5 print(self) # <--- AApp 生成の度に表示

メニュー → A → メニュー → A と繰り返すと

.!app .!app2 .!app3 .!app4

連番で付けられるのがわかると思います。
同様のことが MenuFrame や BApp でも起きています。

解決方法 (いずれかひとつ)

  • destroy を呼ぶ (pack_forget のところを destroy に変更)
  • ウィジェット生成時に name を付ける
  • 新規生成・破棄 とはせずに、表示・非表示にする

注意点: destroy の方法をとった場合は、btnA2_click内で

self.master.gotoB() <--- この時点で AApp は破棄されるため
その後で TextBoxA.get() を参照するとエラーになります。
他の方法の場合は、TextBoxAは破棄されない為、後からでも参照可能。

投稿2020/10/27 17:48

teamikl

総合スコア8664

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

able

2020/10/28 10:13

teamikl様 おかげさまで希望の機能が実装することができました。 また、画面遷移の方法についてもアドバイスをいただきありがとうございます。 いただいたアドバイスを基に改良を行っていこうと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問