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

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

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

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

Tkinter

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

Q&A

解決済

1回答

1248閲覧

(python)Tkinterから呼び出した関数が正しく機能しません。

yoshihoko

総合スコア25

Python 3.x

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

Tkinter

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

0グッド

0クリップ

投稿2019/08/28 09:36

編集2019/08/28 13:36

発生している問題 

weatherget関数を呼び出したときに、変数dateが0で固定され、必ず「今日の天気」を選んだときの表示になってしまう。
↓「今日の天気」以外の項目を選んでも、必ず今日の天気を検索してきてしまう↓

該当のソースコード

1つ目:
test.py

Python3

1 2import tkinter as tk 3import tkinter.messagebox as message 4import os 5import get_weather #ここで後述のget_weather.pyをインポートしています。 6 7def exit(): 8 authwindow=tk.Tk() 9 authwindow.title('認証') 10 authwindow.geometry('175x100') 11 entry=tk.Entry(authwindow) 12 label=tk.Label(authwindow, text='パスコードを入力').pack() 13 entry.pack() 14 15   def authentication(): 16 password=entry.get() 17 if(password=="test"): 18 authwindow.destroy() 19 window.destroy() 20 else: 21 response=message.showerror('認証', 'パスコードが違います') 22 23  def exit(): 24 authwindow.destroy() 25 okbutton=tk.Button(authwindow,text='OK', command=authentication).pack(side=tk.LEFT) 26 cancelbutton=tk.Button(authwindow,text='キャンセル', command=exit).pack(side=tk.RIGHT) 27 28def reboot(): 29 response=message.askyesno('確認', '再起動しますか?') 30 if(response==True): 31 os.system('sudo reboot') 32 else: 33 response=message.showinfo('', '再起動しません。') 34 35def shutdown(): 36 response=message.askyesno('確認', 'シャットダウンしますか?') 37 if(response==True): 38 os.system('sudo poweroff') 39 else: 40 response=message.showinfo('', 'シャットダウンしません。') 41 42def weatherget(): 43 weatherwindow=tk.Tk() 44 weatherwindow.title('天気を調べる') 45 weatherwindow.geometry('150x150') 46 radio_value=tk.IntVar() 47 radio_value.set(0) 48 character={0:'今日の天気',1:'明日の天気',2:'明後日の天気'} 49 tk.Radiobutton(weatherwindow, text=character[0], variable = radio_value, value = 0).pack() 50 tk.Radiobutton(weatherwindow, text=character[1], variable = radio_value, value = 1).pack() 51 tk.Radiobutton(weatherwindow, text=character[2], variable = radio_value, value = 2).pack() 52 def get(): 53 date = radio_value.get() 54 print(date) 55 get_weather.weather(date) 56 weatherwindow.destroy() 57 tk.Button(weatherwindow, text='調べる', command=get).pack() 58 weatherwindow.mainloop() 59 60window=tk.Tk() 61menubar=tk.Menu(window) 62sysmenu=tk.Menu(menubar) 63window.attributes("-fullscreen", True) 64button=tk.Button(window,text="天気を調べる", command=weatherget).pack() 65menubar.add_cascade(label='メニュー', menu=sysmenu) 66sysmenu.add_command(label='再起動', command=reboot) 67sysmenu.add_command(label='シャットダウン', command=shutdown) 68sysmenu.add_command(label='開発環境へ', command=exit) 69window.config(menu=menubar) 70 71

2つ目:
get_weather.py

Python3

1import tkinter as tk 2import tkinter.messagebox as msg 3import requests 4import os 5def weather(date): 6 api_url = 'http://weather.livedoor.com/forecast/webservice/json/v1'; 7 payload={'city':'130010'} 8 weather_data = requests.get(api_url, params=payload).json() 9 speech_data=(weather_data['forecasts'][date]['dateLabel'] + 'の天気は、' + weather_data['forecasts'][date]['telop'] ) 10 response=msg.showinfo('天気を調べる', speech_data) 11 12

試したこと

・weatherget関数単独で実行してみた(→何故か動いた。しかし、Tkinterから呼び出すことが私の目標なので、別の解決方法を現在探しています。

補足情報

天気予報を取得するには、LINE株式会社が提供する「Weather Hacks」の「お天気Webサービス」を利用しています。
また、OSは、Linux Debianのバージョン 10(buster)を使用しています。

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

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

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

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

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

guest

回答1

0

ベストアンサー

とりあえず私の環境(Python 3.7)にて下記のコードで問題なく、radio_value の値が変化しているのを確認できましたが。

python

1import tkinter as tk 2 3def weatherget(): 4 weatherwindow=tk.Tk() 5 weatherwindow.title('天気を調べる') 6 weatherwindow.geometry('150x150') 7 radio_value=tk.IntVar() 8 radio_value.set(0) 9 character={0:'今日の天気',1:'明日の天気',2:'明後日の天気'} 10 tk.Radiobutton(weatherwindow, text=character[0], variable = radio_value, value = 0).pack() 11 tk.Radiobutton(weatherwindow, text=character[1], variable = radio_value, value = 1).pack() 12 tk.Radiobutton(weatherwindow, text=character[2], variable = radio_value, value = 2).pack() 13 14 def get(): 15 date = radio_value.get() 16 print(date) 17 #get_weather.weather(date) 18 #weatherwindow.destroy() 19 20 tk.Button(weatherwindow, text='調べる', command=get).pack() 21 weatherwindow.mainloop() 22 23weatherget()

【編集を受けて追記】

今回、サブウィンドウの生成にtk.Tk()を呼んでおりますが、tk.Toplevel()を使用してください。

サブウィンドウを生成する際にトップレベルウィジェット(tk.Tk())を生成してしまいますと、サブウィンドウのmainloop()が動作している間、親ウィンドウのmainloop()が動作しなくなるために不具合を引き起こします。
tk.Toplevel() の場合は親ウィンドウの mainloop() に同居しますので、新たにmainloop() を呼ぶ必要がなく、親ウィンドウとサブウィンドウを同時に動作させることができます。

ということで、weatherget関数を書き換えると以下のようになります。

Python

1def weatherget(main_window): 2 # 変更:tk.Tk ではなく Toplevel(サブウィンドウ) を使う 3 weatherwindow=tk.Toplevel(main_window) 4 # 追加:modal(main_windowのコントロールを抑制する) に設定 5 # これを行わないとサブウィンドウ表示中も親ウィンドウのボタンが押せてしまう 6 weatherwindow.grab_set() 7 weatherwindow.title('天気を調べる') 8 weatherwindow.geometry('150x150') 9 radio_value=tk.IntVar() 10 radio_value.set(0) 11 character={0:'今日の天気',1:'明日の天気',2:'明後日の天気'} 12 tk.Radiobutton(weatherwindow, text=character[0], variable = radio_value, value = 0).pack() 13 tk.Radiobutton(weatherwindow, text=character[1], variable = radio_value, value = 1).pack() 14 tk.Radiobutton(weatherwindow, text=character[2], variable = radio_value, value = 2).pack() 15 def get(): 16 date = radio_value.get() 17 print(date) 18 get_weather.weather(date) 19 weatherwindow.destroy() 20 tk.Button(weatherwindow, text='調べる', command=get).pack() 21 # 削除 : mainloopは親 Windowと共通なのでこの処理はいらない 22 # weatherwindow.mainloop()

また、この変更で関数に引数(main_window : メインウィンドウ)が追加されたので呼び出し側も

Python

1button=tk.Button(window,text="天気を調べる", command=lambda: weatherget(window)).pack()

のように修正する必要があります。

投稿2019/08/28 10:28

編集2019/08/28 23:46
magichan

総合スコア15898

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

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

yoshihoko

2019/08/28 11:34

返信が遅くなってしまい、申し訳ございません。 今追加した完全なソースコードで試してみてください。
magichan

2019/08/28 23:47

なるほど、weatherget はサブウィンドウなのですね。 回答を追記しました。
yoshihoko

2019/08/29 06:09

ご回答ありがとうございます。 教えていただいたコードで、無事動作しました。 未熟な私に丁寧に教えてくださり、本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問