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

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

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

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

Tkinter

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

Q&A

2回答

451閲覧

文字の更新が上手くいかない。

PythonNINJYA

総合スコア17

Python 3.x

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

Tkinter

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

0グッド

0クリップ

投稿2023/03/16 05:35

クトゥルフ神話TRPGのキャラメイクツールをtkinterで作っているのですがサイコロを振るプログラムがどうもうまくいきません。

実現したいこと

・ROLLを押したときに該当箇所のみが変わるようにしたい。
・ALL ROLLを押したときにすべて変わるようにしたい

前提

ボタンを押してもtkinter上の文字が変わらず、最後の8番目のボタンを押したときと、ALL ROLLを押したときだけしか変わりません。しかも数字が同じです。リスト上では変わっています。

該当のソースコード

python3

1import tkinter as tk 2from tkinter import ttk 3import random 4 5root=tk.Tk() 6root.geometry('400x600') 7root.title('クトゥルフ神話ツール') 8flame=tk.Frame(root) 9flame.grid(row=0,column=0) 10 11def roll(i): 12 def x(): 13 status_amount=0 14 if i==2 or i==5: 15 status_amount=random.randint(8,18) 16 amount_status[i]=status_amount 17 else: 18 status_amount=random.randint(3,18) 19 amount_status[i]=status_amount 20 number_set() 21 point_label=tk.Label(flame,text=amount_status[5]*10+amount_status[7]*20, 22 font=('HG丸ゴシックM-PRO',30),foreground='#ff0000') 23 point_label.grid(row=8,column=2) 24 25 return x 26 27def number_set(): 28 global amount_status 29 for i in range(8): 30 var.set(amount_status[i]) 31 amount_label=tk.Label(flame,textvariable=var,font=('HG丸ゴシックM-PRO',30),foreground='#ff0000') 32 amount_label.grid(row=i,column=2) 33 print(amount_status) 34 35def roll_all(): 36 def x(): 37 #global var 38 for i in range(8): 39 status_amount=0 40 if i==2 or i==5: 41 status_amount=random.randint(8,18) 42 amount_status[i]=status_amount 43 else: 44 status_amount=random.randint(3,18) 45 amount_status[i]=status_amount 46 number_set() 47 point_label=tk.Label(flame,text=amount_status[5]*10+amount_status[7]*20, 48 font=('HG丸ゴシックM-PRO',30),foreground='#ff0000') 49 point_label.grid(row=8,column=2) 50 51 return x 52 53 54 55 56status=['STR','CON','SIZ','DEX','APP','INT','POW','EDU'] 57amount_status=[0,0,0,0,0,0,0,0] 58var=tk.IntVar() 59for i in range(8): 60 var.set(amount_status[i]) 61 label=tk.Label(flame,text=status[i],font=('HG丸ゴシックM-PRO',30)) 62 button=tk.Button(flame,text='ROLL',font=('HG丸ゴシックM-PRO',15),command=roll(i)) 63 label.grid(row=i,column=0) 64 button.grid(row=i,column=1) 65 amount_label=tk.Label(flame,textvariable=var,font=('HG丸ゴシックM-PRO',30),foreground='#ff0000') 66 amount_label.grid(row=i,column=2) 67ginou_label=tk.Label(flame,text='技能ポイント',font=('HG丸ゴシックM-PRO',20)) 68ginou_label.grid(row=8,column=1) 69all_push=tk.Button(flame,text='ROLL ALL',font=('HG丸ゴシックM-PRO',15),command=roll_all()) 70all_push.grid(row=8,column=0) 71 72root.mainloop() 73 74

試したこと

IntVerを使ってみましたがうまくいきません。

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

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

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

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

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

guest

回答2

0

よい回答ついているのでおまけです。

動作確認していて作ってしまったのがこちらです。
考えかたは回答と同じです。

  • それぞれのラベルごとに作ったIntVarをamount_statusに格納する
  • 乱数を設定するときに、対応するIntVarを変更する
  • 値を使うときはget()メソッドを使う

python

1import tkinter as tk 2from tkinter import ttk 3import random 4 5root=tk.Tk() 6root.geometry('400x600') 7root.title('クトゥルフ神話ツール') 8flame=tk.Frame(root) 9flame.grid(row=0,column=0) 10 11def roll(i): 12 def x(): 13 global amount_status 14 status_amount=0 15 if i==2 or i==5: 16 status_amount=random.randint(8,18) 17 amount_status[i].set(status_amount) 18 else: 19 status_amount=random.randint(3,18) 20 amount_status[i].set(status_amount) 21 point_label=tk.Label(flame,text=amount_status[5].get()*10+amount_status[7].get()*20, 22 font=('HG丸ゴシックM-PRO',30),foreground='#ff0000') 23 24 point_label.grid(row=8,column=2) 25 26 return x 27 28def roll_all(): 29 def x(): 30 global amount_status 31 for i in range(8): 32 status_amount=0 33 if i==2 or i==5: 34 status_amount=random.randint(8,18) 35 amount_status[i].set(status_amount) 36 else: 37 status_amount=random.randint(3,18) 38 amount_status[i].set(status_amount) 39 point_label=tk.Label(flame,text=amount_status[5].get()*10+amount_status[7].get()*20, 40 font=('HG丸ゴシックM-PRO',30),foreground='#ff0000') 41 point_label.grid(row=8,column=2) 42 43 return x 44 45 46status=['STR','CON','SIZ','DEX','APP','INT','POW','EDU'] 47 48amount_status = [] 49for i in range(8): 50 amount_status.append(tk.IntVar()) 51 52for i in range(8): 53 label=tk.Label(flame,text=status[i],font=('HG丸ゴシックM-PRO',30)) 54 button=tk.Button(flame,text='ROLL',font=('HG丸ゴシックM-PRO',15),command=roll(i)) 55 label.grid(row=i,column=0) 56 button.grid(row=i,column=1) 57 amount_label=tk.Label(flame,textvariable=amount_status[i],font=('HG丸ゴシックM-PRO',30),foreground='#ff0000') 58 amount_label.grid(row=i,column=2) 59 60ginou_label=tk.Label(flame,text='技能ポイント',font=('HG丸ゴシックM-PRO',20)) 61ginou_label.grid(row=8,column=1) 62all_push=tk.Button(flame,text='ROLL ALL',font=('HG丸ゴシックM-PRO',15),command=roll_all()) 63all_push.grid(row=8,column=0) 64 65root.mainloop()

投稿2023/03/16 07:30

TakaiY

総合スコア12763

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

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

0

58行目

Python

1var=tk.IntVar()

でインスタンス化されたvarを各ウィジットに紐づけしているため、すべて同じ数字が表示されてしまいます。amount_statusにあるそれぞれの内容を表示したい場合は、1つ1つに対応するtk.IntVarのインスタンスを作成して各ウィジットに紐づけてあげる必要があります。

断片的な形での提示で申し訳ないのですが、以下のようにしてあげるとよいかと思います。

Python

1var_list = list(tk.intVar() for i in range(8)) 2... 3var_list[i].set(amount_status[i]) 4... 5tk.Label(..., textvariable=var_list[i], ...)

投稿2023/03/16 06:39

yukkeorg

総合スコア985

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

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

PythonNINJYA

2023/03/16 12:18

ナルホド・・・でもなぜ、質問にあるプログラムではリスト(amount_status)の最後の要素が入ってくるのでしょうか?
yukkeorg

2023/03/17 07:11

回答が遅くなりました。 29行目や59行のforループを抜けるときには、amount_statusの一番最後(8番目)の値がvar.set()で設定されるからです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問