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

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

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

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

Tkinter

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

Q&A

解決済

2回答

13311閲覧

あるクラスで入力した値を別クラスに渡したい、もしくは、参照したい。

threeeverytwo

総合スコア49

Python 3.x

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

Tkinter

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

0グッド

1クリップ

投稿2018/03/27 19:34

編集2018/03/28 10:49

前提・実現したいこと

class InputNamePage の frame のエントリで入力された値をclass ProblemPage に渡したい
もしくは、で参照したい。

該当のソースコード

python

1#------------------------------------------------------------------------------ 2# 名前入力ページクラス (継承 : tk.Frame) 3#--------------------------------------------------------------------------- 4class InputNamePage(tk.Frame): 5 6 #--- コンストラクタ 7 def __init__(self, parent, controller): 8 9 # 初期化 10 tk.Frame.__init__(self, parent) 11 12 ### フレーム表示 13 #--- フレーム生成 14 frame = ttk.Frame(self) 15 #--- フレーム配置 16 frame.pack() 17 18 19 ### ユーザー名入力表示 20 #--- ラベル生成 21 # 空白 22 spaceLabel2 = [tk.Label(frame, text="") for column in range(1)] 23 24 # ユーザー名 25 userNameLabelFont = ("Helevetice", 14) 26 userNameLabel =\ 27 ttk.Label(frame, text="ユーザー名:", font=userNameLabelFont) 28 29 #--- ラベル配置 30 # 空白 31 for index in range(1): 32 spaceLabel2[index].grid(row=index, column=0) 33 # ユーザー名 34 userNameLabel.grid(row=4, column=0) 35 36 #--- エントリー生成 37 userName = tk.StringVar() 38 userNameEntry = ttk.Entry(frame, textvariable=userName, width=30) 39 40 #--- エントリー配置 41 userNameEntry.grid(row=4, column=1) 42 43#------------------------------------------------------------------------------ 44# 問題出題ページクラス (継承 : tk.Frame) 45#------------------------------------------------------------------------------ 46class ProblemPage(tk.Frame): 47""" このクラスで上のクラスで入力された値を出力したい。"""

試したこと

Webで検索をかけて調べた。

###追記
■ ProblemFormSelect(途中略記)

python

1class OptionSelectPage(tk.Frame): 2  #--- コンストラクタ 3 def __init__(self, parent, controller): 4   5    #--- ボタン生成 6 val1 = tk.IntVar() 7 val2 = tk.IntVar() 8 val1.set(0) 9 val2.set(0) 10 radioButton1 = ttk.Radiobutton(frame1,\ 11 text="英語 → 日本語",\ 12 variable=val1,\ 13 value=0) 14 15 radioButton2 = ttk.Radiobutton(frame1,\ 16 text="日本語→ 英語 ",\ 17 variable=val2,\ 18 value=1) 19 20 #--- ボタン配置 21 radioButton1.grid(row=5, column=0) 22 radioButton2.grid(row=6, column=0) 23  

■ 画面遷移(上から下の画像にかけて画面遷移します)
イメージ説明
イメージ説明
イメージ説明
イメージ説明
イメージ説明

■ ページを生成しているメインクラス

python

1class WordPracticeApp(tk.Tk): 2 3 #--- コンストラクタ 4 def __init__(self, *args, **kwargs): 5 6 # 初期化 7 tk.Tk.__init__(self, *args, **kwargs) 8 9 # コンテナのフレームを生成 10 container = tk.Frame(self) 11 12 # コンテナ配置 13 container.pack(side="top", fill="both", expand=True) 14 15 # コンテナのグリッドを 1x1 にする 16 container.grid_rowconfigure(0, weight=1) 17 container.grid_columnconfigure(0, weight=1) 18 19 # フレームを格納する配列 20 self.frames = {} 21 22 # ページを格納する配列 23 pages = ( 24 StartPage, 25 #InputNamePage, 26 ReadWordFilePage, 27 OptionSelectPage, 28 ProblemPage, 29 ResultPage, 30 ) 31 32 # それぞれのページに対して 33 for F in pages: 34 35 # フレームを生成 36 frame = F(container, self) 37 38 # フレームを格納 39 self.frames[F] = frame 40 41 # フレームを配置 42 frame.grid(row=0, column=0, sticky="nsew") 43 44 45 # スタートページを表示 46 self.show_frame(StartPage) 47 48 49 #--- フレームを表示 50 def show_frame(self, cont): 51 52 # WordPracticeAppのcontのフレームを格納 53 frame = self.frames[cont] 54 55 # そのフレームを上位層へ 56 frame.tkraise() 57 58 59

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

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

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

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

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

guest

回答2

0

一般的な場合として回答します
継承関係のない独立したクラスでは、クラス内だけでの変数のやり取りは出来ません。
ですので、クラス内の変数に係る処理はすべてそのクラス内のメソッドや関数を使うようにして、そのクラス内で完結するようにします
どうしてもクラス間でやり取りしたいというのであれば、クラス変数、メソッドを外部に公開するようにして、明示的に代入させるなどしなければいけません

というより、そもそもクラスというのは、「とある機能」をまとめた形でパッケージングするもんですんで、他の独立したクラスとの内部的な連携を考えなければならないという時点で設計が間違ってますね

投稿2018/03/28 02:04

y_waiwai

総合スコア87774

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

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

threeeverytwo

2018/03/28 02:34

いや~、すいません。GUIの学習と実装を設計をぶっ飛ばして、同時並行でやっているもので、設計する暇がないのです。オブジェクト指向もあまりまだ理解できていない次第でありまして。精進します。
guest

0

ベストアンサー

どういうキーワードで検索したのかを追記していただくと、回答する時に手間が省けます。

Python

1userName = tk.StringVar() 2userName.get() # ←で値を取得できます。

問題はこの変数:userNameのスコープの範囲がInputNamePage__init__関数内で完結しているため、他のクラスからは参照できません。

txt

1基礎知識として、スコープの知識が必要なため。 2「python スコープ」というキーワードで検索してみてくださいな。

◇クラス間の値の受け渡しには実装方法が複数あります。

案1,スコープを広げてグローバルスコープの変数経由で値を受け渡しする。
メリット:簡単、理解しやすい。
デメリット:C言語のグローバル変数の問題と同様の問題が発生する。あとメモリリークに注意!

Python

1# 1,ソースコードの先頭のimport文の直後の行に追加。 2params = {} 3# 2,InputNamePageの__init__ 4class InputNamePage(tk.Frame): 5 #--- コンストラクタ 6 def __init__(self, parent, controller): 7 userName = tk.StringVar() 8 params['userName'] = userName 9# 3,`ProblemPage`クラス側では`userName.get()`して値を取得する。

案2,InputNamePageとProblemPageのコンストラクタにパラメータを追加して、パラメータ経由で渡す。

コンストラクタ

Python

1def __init__(self, parent, controller, params):

生成側

Python

1params = {} 2InputNamePage(parent, controller, params) 3ProblemPage(parent, controller, params)

Python

1ProblemPageのイベントで呼び出し

値の取得は案1と同様です。
メリットはグローバルモジュールの汚染が防げます。

案3,sqlite3を画面のバックエンドにして、sqlite3経由で値の受け渡しを行う。
簡単には書ききれないので、「sqlite3 画面遷移 python」キーワードで検索してみてくださいな。

◇別案
私がもしも質問文の要件を実装するとしたら、
ユーザー名はウィンドウのタイトルかステータスバー(クラス)を新設して、そこに表示させます。
個々の画面間で受け渡しするような形にはしないと思います。

◇考えられそうな問題
InputNamePageとProblemPageを最初に全部生成している可能性
ProblemPageの生成を後にしてください。

投稿2018/03/28 01:19

umyu

総合スコア5846

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

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

threeeverytwo

2018/03/28 10:46 編集

スタンドアロンのアプリなので、1個人が使用することを想定しているので、ユーザ名は、使わないことにしました。 ただ、ProberemPageの前に、問題の形式を選択するページ(OptionSelectPage)があり、そのページでは、ボタンを選択して、そのボタンの値を、ProblemPageに渡す必要が、今やろうとしている方法だと必要なのです。これを実現しようとすると、上記の案1~3を使えば出来るでしょうか? OptionSelectPageのコードと画面遷移のスクショも追記しておきます。 あと、値の取得が、userName.get()ではどうもできないみたいでした。 これは、おしゃっていただいた通り、生成部分に問題がありそうな気がします。 生成部のコードも追記しておきます。
umyu

2018/03/28 14:29

>KAIJIさんへ 案1~案3でできますがー。作成しているのコードの処理の流れがどう動いているのかをあまり意識していないように見受けられます。まず、現状のプログラムがどう動いているのかをprint文やデバッカーの機能を使って、図解してみてはどうでしょうか?
threeeverytwo

2018/03/29 08:01 編集

えっ、本当ですか。それは、大変申し訳ないです。 では、print文で、可視化してみます。 ご助言有難うございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問