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

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

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

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

Tkinter

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

Q&A

1回答

433閲覧

pythonのtkinterのradiobuttonで選択した項目のvalue値を関数の変数にしようとするとエラーが出る

yoshisuta

総合スコア10

Python 3.x

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

Tkinter

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

0グッド

0クリップ

投稿2022/04/13 15:54

編集2022/04/15 14:21

Tkinterでマップ選択画面にradiobuttonを配置して選んだマップのframeに飛べるシステムを作っています。しかしエラーが出てしまってうまく変数にradiobuttonのvalue値を組み込むことができません。

main.py

1# tkinterのインポート 2import tkinter as tk 3import tkinter.ttk as ttk 4import time 5import program as pg 6import talking as tg 7import keyboard 8import pygame 9 10if __name__ == "__main__": 11 #メインウィンドウの設定 12 root = tk.Tk() 13 root.attributes('-fullscreen', True) 14 root.bind('<Escape>', lambda e: root.destroy()) 15 root.geometry("1920x1200") 16 root.configure(bg='black') 17 root.grid_rowconfigure(0, weight=1) 18 root.grid_columnconfigure(0, weight=1) 19 20 #タイトルウィンドウ設置 21 frame = tk.Frame(root, bg='black') 22 frame.grid(row=0, column=0, sticky="nsew", pady=20) 23 24 #マップ画面 25 main_map = tk.Frame(root, bg='black') 26 main_map.grid(row=0, column=0, sticky="nsew", pady=20) 27 map_img = tk.PhotoImage(file='map.png') 28 map_img_label = tk.Label(main_map, image=map_img, background='black') 29 map_img_label.grid() 30 31 map_radio = tk.IntVar() 32 map_radio.set(0) 33 map_1 = tk.Radiobutton(map_img_label, value=0, variable=map_radio) 34 map_1.place(x=500, y=600) 35 map_2 = tk.Radiobutton(map_img_label, value=1, variable=map_radio) 36 map_2.place(x=1000, y=700) 37 map_3 = tk.Radiobutton(map_img_label, value=2, variable=map_radio) 38 map_3.place(x=1300, y=500) 39 map_select_button = tk.Button(main_map, text='選択', command=lambda:pg.change_map(map_radio)) 40 map_select_button.place(x=1800, y=1000) 41 42 #ろとの塔 43 roto = tk.Frame(root, bg='black') 44 roto.grid(row=0, column=0, sticky="nsew", pady=20) 45 talk_label = tk.Label(roto, text = tg.roto_tell[pg.roto_x]) 46 talk_label.place(x=0, y=800, width=1920, height=300) 47 48 #勇者の集落 49 yuusha = tk.Frame(root, bg='black') 50 yuusha.grid(row=0, column=0, sticky="nsew", pady=20) 51 talk_label = tk.Label(yuusha, text = tg.yuusha_tell[pg.yuusha_x]) 52 talk_label.place(x=0, y=800, width=1920, height=300) 53 54 #天空の洞窟 55 tenku = tk.Frame(root, bg='black') 56 tenku.grid(row=0, column=0, sticky="nsew", pady=20) 57 talk_label = tk.Label(tenku, text = tg.tenku_tell[pg.tenku_x]) 58 talk_label.place(x=0, y=800, width=1920, height=300) 59 60 # frameを前面にする 61 frame.tkraise() 62 63 root.mainloop()

program.py

1import talking as tg 2import time 3import tkinter as tk 4import tkinter.ttk as ttk 5import main 6import pygame 7 8map_no = [roto, yuusha, tenku] 9 10def change_map(var): 11 map_value= var.get() 12 map_no[map_value].tkraise()

error

1 map_no[map_value].tkraise() 2AttributeError: 'str' object has no attribute 'tkraise'

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

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

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

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

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

guest

回答1

0

掲載のコードからは、AttributeError は確認できません。
質問のコードを実行して、同じエラーを再現できるか確認してください。

  • frame.tkraise() の frame が未定義
  • map_no が未定義
  • ikkun モジュールが未定義

map.png ファイルがない。必須ではありませんが、質問に掲載するコードでは、
ファイルを用意しなくてもエラーが出ずに実行できるようにしておくと良いです。

map_no[map_value].tkraise()
AttributeError: 'str' object has no attribute 'tkraise'

自体は、map_no[map_value] が恐らく str 文字列型のデータとなっているので、
tkinter.Widget にある tkraise メソッドが呼び出せません。

tkinter のウィジェットは、tkinter ライブラリ内部ではウィジェットを識別するID (文字列) で扱われる為、
どこかで文字列になってるのかもしれません。
IDの文字列 -> widget 変換には、nametowidget 関数が提供されてますが、
map_no に関するコードが質問に掲載されてないため、詳細はわかりません。


追記: 画面遷移のサンプルコードを掲載

python

1 2 3import tkinter as tk 4 5 6def main(): 7 root = tk.Tk() 8 frame = tk.Frame(root) 9 10 map_01 = tk.Frame(frame, width=600, height=400, bg="red") 11 map_01.grid(row=0, column=0, sticky=tk.NSEW) 12 13 map_02 = tk.Frame(frame, width=600, height=400, bg="blue") 14 map_02.grid(row=0, column=0, sticky=tk.NSEW) 15 16 map_03 = tk.Frame(frame, width=600, height=400, bg="green") 17 map_03.grid(row=0, column=0, sticky=tk.NSEW) 18 19 # NOTE: map_no の定義は 20 # 内容の map_01, map_02, map_03 が見える場所で定義する 21 map_no = [map_01, map_02, map_03] 22 23 # NOTE: change_map の定義は 24 # map_no の見える場所で定義する 25 def change_map(value): 26 map_no[value].tkraise() 27 28 map_radio = tk.IntVar() 29 radio_frame = tk.Frame(root) 30 tk.Radiobutton(radio_frame, 31 variable=map_radio, value=0 32 ).grid(row=0, column=0) 33 tk.Radiobutton(radio_frame, 34 variable=map_radio, value=1 35 ).grid(row=0, column=1) 36 tk.Radiobutton(radio_frame, 37 variable=map_radio, value=2 38 ).grid(row=0, column=2) 39 tk.Button(radio_frame, text="change", 40 command=lambda: change_map(map_radio.get()) 41 ).grid(row=0, column=3) 42 43 radio_frame.pack() 44 frame.pack() 45 46 root.geometry("600x400") 47 root.mainloop() 48 49if __name__ == '__main__': 50 main() 51

追記2: AttributeError: 'str' object has no attribute 'tkraise' の場合

質問と同じエラーを再現とその対処方法です。
但し、map_no の内容次第では nametowidget を適応できない場合もあるので、
変数の中身を確認してください。ここでは ウィジェットの識別子の文字列になってる場合を想定。

python

1 2import tkinter as tk 3 4 5def main(): 6 root = tk.Tk() 7 frame = tk.Frame(root) 8 9 map_01 = tk.Frame(frame, width=600, height=400, bg="red") 10 map_01.grid(row=0, column=0, sticky=tk.NSEW) 11 12 map_02 = tk.Frame(frame, width=600, height=400, bg="blue") 13 map_02.grid(row=0, column=0, sticky=tk.NSEW) 14 15 map_03 = tk.Frame(frame, width=600, height=400, bg="green") 16 map_03.grid(row=0, column=0, sticky=tk.NSEW) 17 18 # NOTE: 質問と同じエラーを起こす為に 19 # ここでは意図的に str 型に変換しますが、 20 # 暗黙の型変換が行われている可能性があります。 21 map_no = [str(map_01), str(map_02), str(map_03)] 22 print(f"{map_no}") 23 24 # XXX: 以下のコードは str.tkraise を呼び出そうとして質問と同じエラー 25 # もし map_no[value] がウィジェットのIDだった場合の解決策が nametowidget 26 # 以下にコメントアウトして示します。 27 # 文字列の内容次第では、全然別の問題だったという事もあります。 28 # (※掲載されてるコードからは解らない箇所) 29 def change_map(value): 30 map_no[value].tkraise() 31 # root.nametowidget(map_no[value]).tkraise() 32 33 map_radio = tk.IntVar() 34 radio_frame = tk.Frame(root) 35 tk.Radiobutton(radio_frame, 36 variable=map_radio, value=0 37 ).grid(row=0, column=0) 38 tk.Radiobutton(radio_frame, 39 variable=map_radio, value=1 40 ).grid(row=0, column=1) 41 tk.Radiobutton(radio_frame, 42 variable=map_radio, value=2 43 ).grid(row=0, column=2) 44 tk.Button(radio_frame, text="change", 45 command=lambda: change_map(map_radio.get()) 46 ).grid(row=0, column=3) 47 48 radio_frame.pack() 49 frame.pack() 50 51 root.geometry("600x400") 52 root.mainloop() 53 54if __name__ == '__main__': 55 main()

投稿2022/04/14 11:00

編集2022/04/16 06:32
teamikl

総合スコア8664

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

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

yoshisuta

2022/04/14 11:14

コードを一部省いてしまったため、そのほかのところは機能しています。 文字列をwidget変換するためのnametowidget関数ですが、 map_value = map_radio.get() としているときに map_valueをnametowidget関数を用いて変換するにはどうしたらいいのでしょうか?
teamikl

2022/04/14 11:25

> map_valueをnametowidget関数を用いて変換するにはどうしたらいいのでしょうか? map_value はラジオボタンで選択された値なので、 この値に nametowidget を適応することは出来ません。 nametowidget にはウィジェットの識別子(文字列)を渡します。 必要な情報 map_no の定義が省かれているので、 まずは、質問を修正し問題のエラーを再現できるコードを掲載してください。
yoshisuta

2022/04/14 12:08

質問修正しました。よろしくお願いいたします。
teamikl

2022/04/14 12:47 編集

質問のコードには関係ない部分が追加されてます。 「map_no の定義」辺りの情報を掲載してください。 追記: talking モジュールも未定義 質問と同じエラーメッセージを再現できない場合、 「質問に掲載されているコード」と「実際に実行してるコード」が違っている可能性もあるので、 一度ここの質問に張ったコードを新しい環境で実行してみてください。
teamikl

2022/04/14 12:38

変更したコードでは、map_no[map_value] から var を渡すように変更されてるので、 エラーメッセージのmap_no[map_value].tkraise() も変わるはずですよね? まずは確認のためにも、一度「質問に掲載したコード」をコピーして実行してください。 もしかすると、map_no[map_value] は map_1, map_2, map_3 をそれぞれ参照したいのかな?
yoshisuta

2022/04/15 14:22

修正しました。map_noの配列の中身をradiobuttonにつけた数字を使って取り出す感じです。
teamikl

2022/04/16 04:20 編集

質問のコードとエラー内容が対応してません。 map_no 内容の変数は main モジュール側の変数なので、 別のエラーになるはずです。 再度確認ですが、「質問に掲載したコード」を実行してみましたか? map_no に Frameオブジェクトが入っていれば、 上述した nametowidget は不要になります。 モジュールの設計上の問題があって main から program をインポート program から main をインポート は循環参照になる可能性があります。 解決策としては、change_map 関数を main.py 側に置くと解消するはずです。 (今掲載されてるコードの)問題の原因は、変数の有効範囲の問題なので、 各変数を何処で定義したか、どこまでの範囲で有効かを詳しく見て下さい。 ※但し、その場合は別のエラーメッセージがでるはずなので、まずは編集中のコードと実行したコードが同じかどうかの確認をお勧めします。 追記: もし今でも同じエラーがでてるなら、 こちらでは再現出来ないので、原因が何かは実際に実行したコードが掲載されないと解りません。 AttributeError: 'str' object has no attribute 'tkraise' の問題は、map_no の有効範囲ではなく、その中に入ってるオブジェクトの内容次第なので、 掲載されたコードと実行したコードが違っている懸念があります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問