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

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

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

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

Python

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

Q&A

解決済

2回答

773閲覧

外側の関数の変数に、内側の関数内で値をいれて、親の関数の変数に反映させたい

shinobuKouno

総合スコア31

Tkinter

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

Python

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

0グッド

0クリップ

投稿2022/12/16 10:40

前提

def font_chooser()で変数font_aを作り、内側のdef fontget()でfont_aに値を入れて返したいのですが、fontget()内で値を入れることはできたのですが、
font_chooser内ではfont_aに値が入りません。font_aに値を入れる方法を教えてください。
もし、以上のように、font_get()の戻り値を、font_chooser()の戻り値にする方法が一般的でないなら、その一般的な方法をご教示ください。
また、今回は連想配列を使用しているのですが、event.widget['font']から、フォント名だけを取り出す方法があれば教えてください。

実現したいこと

内側の関数の戻り値を外側の関数の戻り値にする
ここに実現したいことを箇条書きで書いてください。

該当のソースコード

Python

1import tkinter as tk 2from tkinter import ttk 3import tkinter.font as font 4 5sty_lst = ["標準","BIZ UDGothic","#000000", "#F0F0F0","#F0F0F0","#F0F0F0","#000000", 6 "#FFFFFF","#F4F6FA","#BDD7EE","#5E86B7","#FFFFFF","#FFFFFF","#F4F6FA", 7 "#D8D8DA","#D8D8DA"] 8 9def font_chooser(): 10 font_a = '' 11 root_fontcho = tk.Tk() 12 root_fontcho.title("フォント選択") 13 root_fontcho.geometry("1300x900") 14 root_fontcho.configure(bg=sty_lst[3]) 15 16 def fontget(event): 17 nonlocal font_a 18 font_a = dic_a[event.widget] 19 print('def内:' + font_a) 20 21 def hover_a(event): 22 event.widget['bg'] = sty_lst[13] 23 def anhover_a(event): 24 event.widget['bg'] = sty_lst[3] 25 26 list = tk.font.families() # 使用できるフォントを代入 27 dic_a = {} 28 29 ia = 1 30 ib = 0 31 ic = 0 32 tmpia = 0 33 34 ntb = ttk.Notebook(root_fontcho) 35 r = (len(list) + 90 - 1) // 90 # タブ数 36 37 for _ in range(1,r + 1): #タブを作る回数 38 tab = tk.Frame(ntb) 39 ntb.add(tab, text=str(ia),underline=0) 40 ia += 1 41 ic = 0 42 43 for _ in range(1,91): 44 if ib == 30: 45 ib = 0 46 ic += 1 47 48 if len(list) <= tmpia: 49 break 50 lbl = tk.Label(tab, 51 text=list[tmpia] + ': ' + 'あいうえおABCDEFGHIJK', 52 font=(list[tmpia],10), 53 width=38, 54 anchor=tk.W) 55 lbl.grid(row=ib, column=ic,padx=1,pady=1) 56 dic_a[lbl] = list[tmpia] 57 lbl.bind("<Enter>", hover_a) 58 lbl.bind("<Leave>", anhover_a) 59 lbl.bind("<Double-1>", fontget) 60 ib += 1 61 tmpia += 1 62 63 ntb.pack(expand=True, fill='both', padx=10, pady=10) 64 65 print('defの外:' + font_a) 66 if not font_a == '': 67 print('if内:' + font_a) 68 root_fontcho.destroy() 69 return font_a 70 71 root_fontcho.mainloop() 72 73ftc = font_chooser() 74print('ftc:' + ftc) 75

試したこと

def font_chooser() で、 return fontget も試しましたが駄目でした

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

python 3.10

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

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

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

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

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

guest

回答2

0

ベストアンサー

一番シンプルにするなら、font_chooser関数から値を返すようにします。

python

1def font_chooser(): 2........ 34..... 5... 6 print('defの外:' + font_a) 7 # if not font_a == '': # 削除 8 # print('if内:' + font_a) # 削除 9 # root_fontcho.destroy() # 削除 10 # return font_a # 削除 11 12 root_fontcho.mainloop() 13 return font_a # 追加 14 15ftc = font_chooser() 16print('ftc:' + ftc) 17

補足

下記の部分は起動した直後の1回しか実行(比較)されません。

py

1 if not font_a == '': 2 print('if内:' + font_a) 3 root_fontcho.destroy() 4 return font_a

また、ウィンドウを閉じるまで、下記より下は実行されません。

py

1 root_fontcho.mainloop()

ウィンドウを閉じると、 root_fontcho.mainloop() が終わり、次の行に行きますが
質問文のコードだとそのまま関数が終わるため、font_chooser は None を返すことになります。

質問のコードでは、non local によって、font_a は 関数内関数 fontget と 親関数 font_chooser の間で共有できています。
しかしそもそも font_chooser が font_aを返していないから期待した動作になっていないのだと考えられます。

よって、
root_fontcho.mainloop()
の下に
return font_a
を置けば、一応期待通りの動作になるはずです。

※ 実際のアプリケーションでは font_chooser はサブのダイアログの扱いでメインのウィンドウは他にあるでしょうから、これがベストプラクティスかどうかは不明です。

投稿2022/12/16 11:17

編集2022/12/16 11:28
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

shinobuKouno

2022/12/16 11:34

ありがとうございますm(__)m 期待通りの動きができるようになりました。 >>また、ウィンドウを閉じるまで、下記より下は実行されません。 これが分かりませんでしたので勉強になりました。ありがとうございます。
guest

0

def font_chooser() で、 return fontget も試しましたが駄目でした

fontget関数の戻り値を返すのであれば、
return fontget(なんたら)
ですが、そもそもfontget関数に戻り値が設定されてません。
まずは、その関数で、お望みの結果を返すようにする必要があります

投稿2022/12/16 10:53

編集2022/12/16 10:54
y_waiwai

総合スコア87774

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

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

shinobuKouno

2022/12/16 11:08

ありがとうございます fontget内で return font_a でもダメでした
y_waiwai

2022/12/16 11:23

どういうふうにだめなんでしょうか
shinobuKouno

2022/12/16 11:37

getfontの外側でfont_aが空のままだったのですが、.mainloop()の下に書くことで解決できました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問