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

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

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

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

Python

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

Q&A

解決済

2回答

697閲覧

他のモジュールのクラスメソッドにlistを渡し、そのlist内から一つの文字列を選択させ、その文字を取得したい

shinobuKouno

総合スコア31

Tkinter

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

Python

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

0グッド

0クリップ

投稿2022/11/24 01:15

編集2022/11/24 02:37

前提

'textc.py'モジュールの'testa'クラスのTkinterラベルの文字を、ラベルイベントでlistを引数として他のモジュール'accho.py'モジュールの
'AccountSelecter'クラスの'tk_show'メソッドでlist内の文字列を選択させその値を取得したい

↓のコードではlistを渡せて選択させるまでは出来たのですが、textc.pyモジュールで受け取ることができません。
クラスとクラスメソッドを勉強中の為、クラスメソッドは使用したままで回答をお願いします。

実現したいこと

accho.pyモジュールで選択したlist内の文字列をtextc.pyモジュール内のラベルに表示させたい

該当のソースコード

---textc.py--- import tkinter as tk import accho list = ['aaaa', 'bbbb', 'cccc', 'dddd', 'eeee', 'ffff', 'gggg', 'hhhh', 'iiii', 'jjjj', 'kkkk', 'llll', 'mmmm', 'nnnn', 'oooo', 'pppp', 'qqqq', 'rrrr', 'ssss', 'tttt', 'uuuu', 'vvvv', 'wwww', 'xxxx', 'yyyy', 'zzzz'] class testa: def click_event(event): acc = accho.AccountSelecter.tk_show(list) print(acc) event.widget.config(text=acc) root = tk.Tk() root.title("test_a") root.geometry("670x400") lbl = tk.Label(root,width=60,bg="white") lbl.pack() lbl.bind("<Button-1>", click_event) root.mainloop() ---accho.py--- class AccountSelecter: def __init__(self): pass def tk_show(list): str_xx = '' def lbl_hover(event): event.widget['bg'] = "#00AAE1" def lbl_anhover(event): event.widget['bg'] = "#FFFFFF" def lbl_Double_click(event): str_xx = event.widget.cget("text") root.quit() root.destroy() root = tk.Tk() root.title("使用する文字列をダブルクリック") root.geometry("670x400") font_name = 'MS Gothic' # ラベルの文字サイズ font_size = 9 # ラベルの文字色 ia = len(list) * 15 frm_a = tk.Frame(root) frm_a.pack(fill=tk.BOTH, expand=tk.YES) cnv = tk.Canvas(frm_a, relief=tk.FLAT) cnv.pack(fill=tk.BOTH, expand=tk.YES) frm_b = tk.Frame(cnv) frm_b.pack(anchor=tk.NW, fill=tk.Y, expand=tk.YES) cnv.create_window(0, 0, window=frm_b, anchor=tk.NW) ybar = tk.Scrollbar(cnv, orient=tk.VERTICAL) ybar.pack(side=tk.RIGHT, fill=tk.Y) ybar.config(command=cnv.yview) cnv.config(yscrollcommand=ybar.set) cnv.config(scrollregion=(0, 0, 1600, ia)) column_pos = 0 row_pos = 0 for v in list: if column_pos == 3: column_pos = 0 row_pos += 1 lbl_xx = tk.Label(frm_b, width=35, text=v, relief=tk.FLAT, font=(font_name, font_size)) lbl_xx.grid(row=row_pos, column=column_pos) # ,padx=5,pady=5,ipady=3) lbl_xx.bind("<Enter>", lbl_hover) lbl_xx.bind("<Leave>", lbl_anhover) lbl_xx.bind("<Double-1>", lbl_Double_click) column_pos += 1 root.mainloop() return str_xx if __name__ == "__main__": tk_show()

補足情報(FW/ツールのバージョンなど)

Python 3.10.5
Tkinter 8.6

よろしくお願いします。

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

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

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

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

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

can110

2022/11/24 01:24

提示コードは正しいでしょうか?textc.pyは実行できないようです。
shinobuKouno

2022/11/24 02:38

すみません。修正いたしました。
guest

回答2

0

ベストアンサー

ダブルクリック時に呼び出されるイベントでは
lbl_Double_click 関数 内のローカル変数へ値を設定しているので、
tk_show() が返す変数の値を変更するには、lbl_Double_click 関数の外側
nonlocal で宣言する必要があります。

python

1 def lbl_Double_click(event): 2 nonlocal str_xx

クラスとクラスメソッドを勉強中の為、クラスメソッドは使用したままで回答をお願いします。

質問とは関連のない部分ですが、クラスの扱いで幾つか問題があります。
クラスの再利用が出来なかったり、意図しない挙動の原因に成り得るので、
修正をお勧めします。

  • クラスの宣言部で実行されるコードを書いている class testa

 import 時にコードが実行される為、再利用が出来ません。

  • accho.py if __name__ == "__main__": 内で tk_show は未定義

 もしくはインデントが間違ってるのかもしれませんが、accho.py ファイルの単体実行できません。

  • インスタンス変数 (self) が殆ど使われていないので、クラスが名前空間としてしか機能していない

 本来はこれはモジュールの役割です。


また、tkinter では tkinter.Tk() のインスタンスは複数作らない方が良いです。
イベントループが入れ子になってしまう為、これもイベントの挙動で問題になる場合があります。
複数のウィンドウが必要な場合、2つ目以降のウィンドウには tkinter.Toplevel を使い
モーダル・ダイアログとして実装してください。

クラスでは tkinter.Frame 上にウィジェットを配置し
各ファイルのメイン関数で tkinter.Tk のインスタンスを作る構成にすると、
testc から accho を利用する時には Toplevel 上に配置するダイアログの部品としてクラスを再利用できます。

追記: 例えば現在のコードでは、click_event は複数回呼び出す事が出来てしまい、
親ウィンドウを先に閉じるとエラーが起こります。
Toplevel を使い、モーダルダイアログとして実装すればこういった挙動を解消できます。

投稿2022/11/24 03:38

編集2022/11/24 03:47
teamikl

総合スコア8664

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

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

0

別Windowsの値を取得することができるようになりました。ありがとうございます。
それと質問外の事も勉強になりました。
selfの使いどころがまだ理解できていないためこれから勉強していきたいと思います。

投稿2022/11/24 11:48

shinobuKouno

総合スコア31

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問