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

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

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

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

Tkinter

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

Q&A

解決済

2回答

10657閲覧

Tkinterでリアルタイムで時間を表示したい

person

総合スコア223

Python 3.x

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

Tkinter

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

0グッド

0クリップ

投稿2020/01/28 06:44

編集2020/01/28 07:31

Tkinterで時間表示をリアルタイム更新したいです。

以前とは異なり、main()内にTkinterのウィジェットを記述することにしました。(後々必要になりそうなので)

そのため、時間表示のラベルもmain()内に記述しているのですが、Threadを立てたり、ウィジェット変数winを呼び出ししている部分でエラーが発生してしまいます。基本的に画面を表示したままの状態なので戻り値を使うことは無理だと思いグローバル変数を使おうと思ったのですが、ウィジェット変数のため普通の変数と違い、初期値の代入でうまくいかず(tk.Tk()を一時的に代入した後destroy()したがエラーが出てしまった)変数を共有することができません。

どなたか対処方法を教えてくださると幸いです。もちろん以前と違う対処方法を提示してくれてもいいです。

Python

1import tkinter as tk 2from datetime import datetime 3import time 4import threading 5import queue 6 7def main(): 8 win = tk.Tk() 9 10 f1 = tk.Frame(win) 11 f1.grid() 12 f2 = tk.Frame(win) 13 f2.grid(sticky="w") 14 15 time_label = tk.Label(f1, text="") 16 time_label.grid() 17 b = tk.Button(f2, text="Button") 18 b.grid() 19 20 win.mainloop() 21 22if __name__ == "__main__": 23 main() 24 25 26 """ 前回ご教授いただいた内容 27 28 #Queue(キュー)を生成(win生成前のLabel書き換え防止 29 message_queue = queue.Queue() 30 31 #現在日時の更新 32 is_valid = True 33 def print_nowtime(): 34 while is_valid: 35 now = datetime.now() 36 message_queue.put("{0:%Y/%m/%d %H:%M:%S}".format(now)) 37 time.sleep(1) 38 39 #ウィンドウクローズ時の、時刻表示ループフラグ終了用 40 def on_closing(): 41 global is_valid 42 is_valid = False 43 thread.join() 44 win.destroy() 45 46 #Queueを確認しLabelを更新 47 def check_queue(): 48 try: 49 msg = message_queue.get(0) 50 time_label["text"] = msg 51 except queue.Empty: 52 pass 53 54 #5ms後に再度この関数を呼ぶ(main thread上で動作) 55 win.after(5, check_queue) 56 57 #起動後すぐにcheck_queue関数を1度呼ぶように設定 58 win.after(0, check_queue) 59 #ウィンドウクローズ時の、時刻表示ループフラグ終了用 60 win.protocol("WM_DELETE_WINDOW", on_closing) 61 62 """

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

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

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

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

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

guest

回答2

0

ベストアンサー

基本的に画面を表示したままの状態なので戻り値を使うことは無理だと思いグローバル変数を使おうと思ったのですが、ウィジェット変数のため普通の変数と違い、初期値の代入でうまくいかず(tk.Tk()を一時的に代入した後destroy()したがエラーが出てしまった)変数を共有することができません

tkinterの場合、グローバル変数が嫌な場合、クラスに閉じ込めてしまうのが一般的かと思いますが、今回のような単純な機能を実現する場合には、以下のようにlambdaを利用して変数を引き回してしまうやり方もあります。

python

1 2import tkinter as tk 3from datetime import datetime 4#import time 5 6def chk_time(win, ltext): 7 now = datetime.now() 8 stime = "{0:%Y/%m/%d %H:%M:%S}".format(now) 9 ltext.set(stime) 10 11 win.after(5, lambda : chk_time(win, ltext)) 12 13def main(): 14 win = tk.Tk() 15 16 f1 = tk.Frame(win, height=100, width=100) 17 f1.grid() 18 f2 = tk.Frame(win) 19 f2.grid() 20 21 ltext = tk.StringVar() 22 time_label = tk.Label(f1, textvariable=ltext) 23 time_label.grid() 24 b = tk.Button(f2, text="exit", command=lambda: win.quit()) 25 b.grid() 26 27 28 win.after(5, lambda : chk_time(win, ltext)) 29 win.mainloop() 30 31main() 32

投稿2020/01/28 08:42

t_obara

総合スコア5488

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

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

person

2020/01/30 02:07

ありがとうございます。
guest

0

指定時間経過後にメソッドを呼び出すafterメソッドを使えば、スレッドを使うまでもなく時間表示できます。参考になるホームページがいくつもありますので、ご案内します。

アナログ時計 - お気楽 Python/Tkinter 入門

Tkinter 入門 - 3. Label だけでタイマーを作ろう

投稿2020/01/28 08:14

dodox86

総合スコア9183

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問