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

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

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

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

Python

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

Q&A

解決済

pythonのtkinterボタンを押したときの関数の呼び出しができません。

tera877
tera877

総合スコア5

Tkinter

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

Python

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

1回答

0グッド

0クリップ

195閲覧

投稿2022/11/22 05:53

前提

pythonのtkinterで簡易的なタイピングゲームを作っています。
実行して遊び方のボタンをクリックしたら別のラベルを表示し、タイトルに戻るというボタンを押したら初期画面に戻るようにしたいです。そのため、タイトルに戻るボタンを押したら、commandでmain()という初期画面を設定している画面に変更する関数を呼び出そうとしているのですが、呼び出せません。

実現したいこと

タイトルに戻るというボタンを押したら初期画面に戻り、それを何回でも続けられるようにしたいです。

発生している問題・エラーメッセージ

Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\nonch\AppData\Local\Programs\Thonny\lib\tkinter_init_.py", line 1705, in call
return self.func(*args)
File "C:\Users\nonch\Documents\pythonフォルダー\keses.py", line 74, in main
title_label.pack(ipady=60)
File "C:\Users\nonch\AppData\Local\Programs\Thonny\lib\tkinter_init_.py", line 2143, in pack_configure
+ self._options(cnf, kw))
_tkinter.TclError: bad window path name ".!label7"

該当のソースコード

python

import tkinter as tk

root = tk.Tk()
root.geometry("1200x600")
root.title("タイピングゲーム")

words = ["ishikawa", "kanazawa", "hokuriku","nagano"]

index = 0
number_of_words = 0

#関数内で使うグローバル変数
word_label = tk.Label(text=words[index], foreground="#66CCFF", font=("",50))
ans_label = tk.Label(text="", font=("",60)) #キー入力の受け取り

count_label = tk.Label(text=4, font=("",100)) #スタートカウントダウンの消去
time_left_label = tk.Label(text="残り時間: 秒", font=("",20))
timer_label = tk.Label(text=31, font=("",20))
number_of_words_label = tk.Label(text=f"タイプワード数:{number_of_words}", font=("",20))

num = 4
timer_num = 31

#####タイプ画面#####
def create_widgets():
word_label.pack(ipady=100)
ans_label.pack()
time_left_label.place(x=0, y=0)
timer_label.place(x=140, y=0)
number_of_words_label.place(x=0, y=50)
timer()

def timer():
global timer_num
if timer_num == timer_label["text"]:
timer_num -= 1
timer_label.configure(text=timer_num)
if timer_num > 0:
root.after(1000, timer)

#####カウントダウンとウィジェットの消去#####
def countdown():
start_button.destroy()
title_label.destroy()
rule_button.destroy()
count_label.pack(expand=True)
global num
if num == count_label["text"]:
num -= 1
count_label.configure(text=num)
if num > 0:
root.after(1000, countdown)

elif num == 0: count_label.destroy() create_widgets()

#####遊び方#####
def rule():
rule_label.pack(ipady=60)
title_label.destroy()
rule_button.destroy()
start_button.destroy()
return_button.pack()

title_label = tk.Label(text="タイピングゲーム", font=("",50)) #グローバル変数として定義しないと関数内で消去できない
rule_button = tk.Button(text="遊び方", font=("",30), command=rule)
start_button = tk.Button(text="スタート", font=("",30), command=countdown)
def main():
#####初期画面#####
#title_label = tk.Label(text="タイピングゲーム", font=("",50)) #グローバル変数として定義しないと関数内で消去できない
title_label.pack(ipady=60)
#rule_button = tk.Button(text="遊び方", font=("",30), command=rule)
rule_button.place(x=750, y=300)
#start_button = tk.Button(text="スタート", font=("",30), command=countdown)
start_button.place(x=250, y=300)

main()

rule_label = tk.Label(text="~遊び方~", font=("",50))
return_button = tk.Button(text="タイトルに戻る", font=("",30), command=main)

#####キー入力#####
def type_event(event):
global index
global number_of_words
ans_label["text"] += event.keysym
if ans_label["text"] == word_label["text"]:
ans_label.configure(text="")
index += 1
word_label.configure(text=words[index])
number_of_words += 1
number_of_words_label.configure(text=f"タイプワード数:{number_of_words}")

elif event.keysym == "BackSpace": text = ans_label["text"] ans_label["text"] = text[:-10]

root.bind("<KeyPress>", type_event) #関数とキー入力の紐づけ

root.mainloop()

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

teamikl

2022/11/22 07:59

コードを実行して見ないと問題解決が難しい場合もあるので、 コードは、markdown 記法のコード導入内に記載してください。 Python のコードはインデント情報が失われてしまいます。

回答1

1

ベストアンサー

エラーメッセージからの推測ですが、
ウィジェットが破棄(destroy) されている為、
再度の配置 packや place は出来ません。

表示非表示の切り替えは、pack/pack_forget を用います。
place で配置の場合は place_forget。

多くのウィジェットを個別に表示非表示切り替えは大変なので、
タイトル画面と遊び方画面をそれぞれ別のFrame に配置し、
親ウィジェットとなるFrameの表示切替で対応できます。

他には、Frame をレイヤーの様に重ねて、
上に持ってくるFrameを切り替える実装方法もあります。
詳しくは、「画面遷移」等をキーワードに調べて見て下さい。

投稿2022/11/22 07:55

teamikl

総合スコア8557

spoofy_dragon👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

tera877

2022/11/22 08:15

ご指摘いただいた部分を修正したらしっかりと動作しました。ありがとうございました。

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

ただいまの回答率
86.02%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Tkinter

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

Python

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