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

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

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

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

Python

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

Q&A

解決済

2回答

3571閲覧

python グローバル変数が定義されていないと言われるエラー

mikku_taka

総合スコア20

Tkinter

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

Python

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

0グッド

0クリップ

投稿2019/07/29 14:32

Tkinterを用いて、ウィンドウ上に画像を出力し、ボタンを押すとウィンドウを削除するプログラムを作っています。
ウィンドウが出力され、削除ボタンをクリックしたところ以下のエラー文が出力されました。

Exception in Tkinter callback Traceback (most recent call last): File "C:\Users\hogehoge\Anaconda3\lib\tkinter\__init__.py", line 1705, in __call__ return self.func(*args) File "<ipython-input-10-05a705ec1967>", line 14, in deleteEntry root.destroy() NameError: name 'root' is not defined

rootが定義されていないと出ていますが、ソースの9行目にグローバル変数として定義しています。
なのになぜこのようなエラーが出るか分からないです。解決策をお願いします。

プログラムの大体の流れは、ウィンドウ上に出力された「消すボタン」をクリックすると
deleteEntry関数を呼び(109行)、ウィンドウ(root)を削除します。

Python

1#画像&マウスjpgpng対応v7 2#-*- coding: utf8 -*- 3import sys 4import tkinter as tk 5from PIL import Image, ImageTk 6import urllib.request as req 7import os 8 9global root 10# ボタンが押されたら呼び出される関数 11def deleteEntry(event): 12 # Entryの中身をすべて削除します 13 root.destroy() 14 15def main(): 16 ################################ 17 root = tk.Tk() 18 root.geometry('900x400') 19 root.title('IMG') 20 img={} 21 for i in range(1,4): 22 if os.path.exists(str(i)+'.png'): 23 img[i] = Image.open(open(str(i)+'.png', 'rb')) 24 img[i].thumbnail((200, 200), Image.ANTIALIAS) #画像の大きさ最大値 25 img[i] = ImageTk.PhotoImage(img[i]) # 表示するイメージを用意 26 else : 27 img[i] = Image.open(open(str(i)+'.jpg', 'rb')) 28 img[i].thumbnail((200, 200), Image.ANTIALIAS) #画像の大きさ最大値 29 img[i] = ImageTk.PhotoImage(img[i]) # 表示するイメージを用意 30 31 canvas={} 32 xx=0 33 for i in range(1,4): 34 canvas[i] = tk.Canvas( 35 root, # 親要素をメインウィンドウに設定 36 width=500, # 幅を設定 37 height=500 # 高さを設定 38 #relief=tk.RIDGE # 枠線を表示 39 # 枠線の幅を設定 40 ) 41 #PILでjpgを使用 42 canvas[i].place(x=xx,y=0) #画像の座標 43 xx=xx+300 44 canvas[i].create_image( # キャンバス上にイメージを配置 45 0, # x座標 46 0, # y座標 47 image=img[i], # 配置するイメージオブジェクトを指定 48 tag="illust", # タグで引数を追加する。 49 anchor=tk.NW # 配置の起点となる位置を左上隅に指定 50 ) 51 52 ################################ 53 54 # Buttonを設置してみる 55 Button1 = tk.Button(text=u'何も起こらないボタン') 56 Button1.place(x=350, y=230) 57 # Buttonを設置してみる 58 Button2 = tk.Button(text=u'消すボタン',) 59 Button2.bind("<Button-1>", deleteEntry) # ボタンが押されたときに実行される関数をバインドします 60 Button2.place(x=350, y=255) 61 62 root.mainloop() 63 64# main関数呼び出し 65if __name__ == "__main__": 66 main()

よろしくお願いします。

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

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

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

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

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

guest

回答2

0

globalで定義されているroot変数と、main関数内で定義されているroot変数は、名前は同じですが、別のオブジェクトを指しています。そのためroot = tk.Tk()では、rootには何も代入されていませんのでundefinedになります。

この記事が参考になるかと
https://uxmilk.jp/12505

投稿2019/07/29 14:40

Yhaya

総合スコア439

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

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

mikku_taka

2019/07/29 15:43

多言語での習慣のおかげで先入観が生まれていました。 解説ありがとうございます
guest

0

ベストアンサー

global の定義は、関数の中で行いましょう

python

1# ボタンが押されたら呼び出される関数 2def deleteEntry(event): 3 global root 4 # Entryの中身をすべて削除します 5 root.destroy()

「python global」でぐぐると使い方が出てきます

投稿2019/07/29 14:38

編集2019/07/29 14:51
y_waiwai

総合スコア87719

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

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

mikku_taka

2019/07/29 15:37

main関数内でglobal定義したところ、うまくいきました。 思い込みと検索不足が原因です。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問