Python脚本仅适用于IDLE

时间:2016-12-10 12:54:07

标签: python python-3.x tkinter

我已经有一段时间了。但是,它只在我从IDLE启动时运行;如果我尝试从桌面运行它,它不会启动。这是一个用Tkinter制作的时钟。

import time

from tkinter import *

def showTime():

    canvas.delete('text')
    if True:
        actualTime = time.localtime()

        text = canvas.create_text((100,50,),
                                  text =(actualTime[3],actualTime[4],actualTime[5]),
                                  fill="white",
                                  font=("Verdana",20,"bold"),
                                  tag="text")

    root.after(1000,showTime)

if "__main__" == __name__:

    root = Tk()

    root.resizable(False,False)
    root.title("Clock")

    canvas = Canvas(root, width=200, height=100,bg="black",cursor="target")
    canvas.create_rectangle((20,20),(180,80),outline="ghostwhite")
    canvas.pack()

    showTime()

1 个答案:

答案 0 :(得分:4)

您需要启动Tkinter主循环。只需添加

root.mainloop()

之后的脚本末尾
showTime()

呼叫。

你的脚本在IDLE中运行的原因是IDLE本身是一个Tkinter程序,它已经有this answer中提到的事件循环。

顺便说一句,if True:中的showTime声明毫无意义。

FWIW,这是您添加了mainloop调用的程序,以及其他一些小的更改。最好避免使用“星号”导入,因为它们会使用导入的名称来混淆您的命名空间,例如from tkinter import *会带来超过130个名称。这可能会导致与您自己定义的名称发生冲突,除非您非常熟悉Tkinter定义的每个名称,但如果您使用星型导入与其他模块碰巧使用Tkinter使用的名称,则会特别成问题。

import time
import tkinter as tk

def showTime():
    canvas.delete('text')
    actualTime = time.localtime()

    text = canvas.create_text((100, 50),
        text = actualTime[3:6],
        fill="white",
        font=("Verdana", 20, "bold"),
        tag="text")

    root.after(1000, showTime)

if "__main__" == __name__:
    root = tk.Tk()

    root.resizable(False,False)
    root.title("Clock")

    canvas = tk.Canvas(root, width=200, height=100, bg="black", cursor="target")
    canvas.create_rectangle((20, 20), (180, 80), outline="ghostwhite")
    canvas.pack()

    showTime()
    root.mainloop()

正如Bryan Oakley在评论中提到的,最好只更新Canvas Text项的文本字符串,而不是删除旧的Text项并每秒构建一个新文本项。所以这是从您的代码派生的新版本。

我使用time.strftime来构建时间字符串,因为它提供了比仅仅切片struct_time返回的time.localtime对象更好的输出:它总是使用2位数来表示小时,分钟和秒组件,您可以轻松地将冒号(或其他)添加到格式字符串。有关strftime提供的所有格式选项,请参阅链接的文档。

我还把GUI放到了一个类中。这对于这样一个简单的GUI来说并不是必需的,但这是一个很好的习惯,因为它使代码更加模块化。

import tkinter as tk
from time import strftime

class Clock:
    def __init__(self):
        root = tk.Tk()
        root.title("Clock")
        root.resizable(False, False)

        self.canvas = canvas = tk.Canvas(root, width=200, height=100, 
            bg="black", cursor="target")
        canvas.create_rectangle((20, 20), (180, 80), outline="ghostwhite")
        canvas.create_text((100, 50), tag = "text",
            fill="white", font=("Verdana", 20, "bold"))
        canvas.pack()

        self.show_time()
        root.mainloop()

    def show_time(self):
        w = self.canvas
        w.itemconfig("text", text=strftime('%H %M %S'))
        w.after(1000, self.show_time)

if "__main__" == __name__:
    Clock()