我为我制作的智能镜子设计了一个基本界面。我将其编码为包括时间、日期和每24小时刷新一次的几个短语。这些短语只是一些随机引用的例子。
我想知道是否有任何方法,我可以简化这段代码,甚至改进界面的布局。
import tkinter as tk
import sys
import time
import calendar
import random
import datetime as dt
from tkinter import *
# Root is the name of the Tkinter Window. This is important to remember.
root=tk.Tk()
""" DICTIONARY PHRASES """
phrases = [" I never had a policy; I have just tried to do my very best each and every day. -- Abraham Lincoln",
" There are some things you learn best in calm, and some in storm. -- Willa Cather",
" If a man does his best, what else is there? -- George S. Patton"]
class Clock(tk.Label):
""" Class that contains the clock widget and clock refresh """
def __init__(self, parent=None, seconds=True, colon=False):
"""
Create and place the clock widget into the parent element
It's an ordinary Label element with two additional features.
"""
tk.Label.__init__(self, parent)
self.display_seconds = seconds
if self.display_seconds:
self.time = time.strftime('%I:%M:%S %p')
else:
self.time = time.strftime('%I:%M:%S %p').lstrip('0')
self.display_time = self.time
self.configure(text=self.display_time, width=11)
if colon:
self.blink_colon()
self.after(200, self.tick)
def tick(self):
""" Updates the display clock every 200 milliseconds """
if self.display_seconds:
new_time = time.strftime('%I:%M:%S %p')
else:
new_time = time.strftime('%I:%M:%S %p').lstrip('0')
if new_time != self.time:
self.time = new_time
self.display_time = self.time
self.config(text=self.display_time)
self.after(200, self.tick)
def blink_colon(self):
""" Blink the colon every second """
if ':' in self.display_time:
self.display_time = self.display_time.replace(':',' ')
else:
self.display_time = self.display_time.replace(' ',':',1)
self.config(text=self.display_time)
self.after(1000, self.blink_colon)
class FullScreenApp(object):
def __init__(self, master, **kwargs):
self.master=master
pad=3
self._geom='200x200+0+0'
master.geometry("{0}x{1}+0+0".format(
master.winfo_screenwidth()-pad, master.winfo_screenheight()-pad))
master.bind('<Escape>',self.toggle_geom)
def toggle_geom(self,event):
geom=self.master.winfo_geometry()
print(geom,self._geom)
self.master.geometry(self._geom)
self._geom=geom
def phrase_refresh():
new_phrase = random.choice(phrases)
e.configure(text=new_phrase, wrap=650) # e is your label
root.after(86400, phrase_refresh) # Delay measured in milliseconds. Currently set to 24 hours. (There are 86400 milliseconds in a day)
return new_phrase
# Sets background color to black
root.configure(bg="black")
# Removes the window bar at the top creating a truely fullscreen
root.wm_attributes('-fullscreen','true')
tk.Button(root, text="", bg="black", fg="black", command=lambda root=root:quit(root)).pack()
#Spacer
v = Label(root, text="", fg="white", bg="black")
v.pack(anchor=NW)
# this displays the clock known as clock1
clock1 = Clock(root)
clock1.pack(anchor=NW)
# This gives the clock format.
clock1.configure(bg='black',fg='white',font=("helvetica",60))
# Add the date to the tkinter window
w = Label(root, text=f"{dt.datetime.now():%a, %b %d %Y}", fg="white", bg="black", font=("helvetica", 30), width=16)
w.pack(anchor=NW)
#Spacer
s = Label(root, text="", fg="white", bg="black")
s.pack(anchor=NW)
#Spacer
p = Label(root, text="", fg="white", bg="black")
p.pack(anchor=NW)
# Add the phrase to the tkinter window
e = Label(root, fg="white", bg="black", font=("helvetica", 17))
phrase_refresh()
e.pack(anchor=NW)
root.mainloop()
发布于 2020-02-01 06:41:57
以下是一些评论:
消除额外/未使用的进口
最好是从文件(或从“每日引用”网站(RSS提要))中加载引号。这样,您就不必编辑源代码来添加新的源了。
没有必要做一个单独的时钟类。这似乎使事情复杂化了。下面的代码在回调计时器上有一个函数。它“超过样本”的时间为每秒5倍。当第二天(可能是任何事情)发生变化时,将调用一个函数来更新时间/日期/短语。
时间格式显示秒,无论display_seconds是真是假。
没有使用类FullScreenApp。
这是我对展示部分的看法。从文件或URL中获取引号对读者来说是一项练习:
import datetime
import random
import tkinter as tk
MESSAGE_WIDTH = 400
SHOW_SECONDS = False
BLINK_COLON = True
""" DICTIONARY PHRASES """
phrases = [
"I never had a policy; I have just tried to do my very best each and every day. -- Abraham Lincoln",
"There are some things you learn best in calm, and some in storm. -- Willa Cather",
"If a man does his best,\n what else is there? -- George S. Patton",
"Better to write for yourself and have no public, than to write for the public and have no self. -- Cyril Connolly",
"Life is far too important a thing ever to talk seriously about. -- Oscar Wilde",
"Indeed, history is nothing more than a tableau of crimes and misfortunes. -- Voltaire",
"In great affairs men show themselves as they wish to be seen; in small things they show themselves as they are. -- Nicholas Chamfort",
"The first step to getting the things you want out of life is this: Decide what you want. -- Ben Stein",
"Life is what happens to you while you're busy making other plans. -- John Lennon",
"For four-fifths of our history, our planet was populated by pond scum. -- J. W. Schopf",
"History will be kind to me for I intend to write it. -- Sir Winston Churchill",
"History is the version of past events that people have decided to agree upon. -- Napoleon Bonaparte",
"You create your opportunities by asking for them. -- Patty Hensen",
"If everyone had a dad like mine, no one would have sex tapes. -- Tina Fey"
]
root = tk.Tk()
root.configure(bg="black")
prev_time = datetime.datetime(1,1,1)
time_display = tk.StringVar(root, " "*len(" HH:MM:SS PM "))
date_display = tk.StringVar(root, " "*len("aaa, bbb dd, YYYY"))
phrase_display = tk.StringVar(root, " "*len(max(phrases, key=len)))
author_display = tk.StringVar(root, " "*MESSAGE_WIDTH)
def tick():
global prev_time
curr_time = datetime.datetime.now()
if curr_time.second != prev_time.second:
update_time(curr_time)
if curr_time.second//15 != prev_time.second//15: # this is for testing, it makes the quote update every 15 seconds
# if curr_time.day != prev_time.day: # normally use this one to update quote every day
update_phrase()
if curr_time.day != prev_time.day:
update_date(curr_time)
prev_time = curr_time
root.after(200, tick)
def update_date(curr_time):
date_display.set(f"{curr_time:%a, %b %d, %Y}")
def update_phrase():
phrase, author = random.choice(phrases).split('--')
phrase_display.set(phrase.strip())
author_display.set(f"-- {author.strip()}")
def update_time(curr_time):
# colon no colon
fmt=[[" %H:%M %p ", " %H %M %p "], # without seconds
[" %H:%M:%S %p ", " %H %M %S %p "] # with seconds
][SHOW_SECONDS][BLINK_COLON and curr_time.second % 2]
time_display.set(f"{curr_time:{fmt}}")
# Removes the window bar at the top creating a truely fullscreen
#root.wm_attributes('-fullscreen','true')
tk.Button(root, text="quit", bg="black", fg="red", command=root.quit).pack()
#Spacer
tk.Label(root, text="", fg="white", bg="black").pack()
# this displays the clock known as clock
clock = tk.Label(root, textvariable=time_display, bg='black',fg='white',font=("helvetica",60))
clock.pack()
# Add the date to the tkinter window
date = tk.Label(root, textvariable=date_display, fg="white", bg="black", font=("helvetica", 30), width=16)
date.pack()
#double height Spacer
tk.Label(root, text="\n\n", fg="white", bg="black").pack()
# Add the phrase to the tkinter window
text = tk.Message(root, textvariable=phrase_display, fg="white", bg="black", font=("helvetica", 17), width=400, justify="left")
text.pack()
author = tk.Message(root, textvariable=author_display, fg="white", bg="black", font=("helvetica", 17), width=400, justify='right', anchor='e')
author.pack()
#Spacer
tk.Label(root, text="", fg="white", bg="black").pack()
# starts the clock
tick()
root.mainloop()
# In some developement environments root.quit doesn't fully destroy the application; hence
# the call to root.destroy(). But clicking the close button (the 'X') on a window does destroy
# the application, so calling root.destroy() raises a TclError for trying to destroy it a
# second time. This quiets the error message.
try:
root.destroy()
except tk.TclError:
pass
发布于 2020-02-02 02:36:08
恭喜你写了一个tk程序。他们可能很难。
将代码从顶层移出是可以在任何程序中进行的改进。顶层代码创建全局变量,使下面可能使用的内容不清楚,依此类推。你可以这么做:
def main():
# Sets background color to black
root.configure(bg="black")
...
except tk.TclError:
pass
main()
这可能看起来很小,但它使我们更容易看到root
、time_display
和其他方面是全球性的,但author
却不是。
一次只修一次。继续攻击!记笔记。
发布于 2020-02-21 15:12:56
开局不错,但有几件事应该清理干净。
试着遵循一个标准。最好是PEP8。在=
之间有额外的间隔,而在某些地方,,
之间没有间隔,而且它很混乱。
from tkinter import *
这是出于两个原因。首先,您已经在执行import tkinter as tk
,因此不需要第二次导入tkinter。如果导入的名称重叠并被覆盖,两个import *
可能会导致问题。tick
代码。一次在__init__
,一次在tick
。您可以删除__init__
中的实例,只需立即调用tick,同时在init中为self.time
和self.display_time
添加一个默认值。200
毫秒。这比你需要的要多5倍。每隔1秒就够了。不需要调用该函数比所需的多5倍。FullScreenApp
。所以要么在某个地方实现它,要么把它移除。return
in phrase_refresher
对你没有任何帮助。它返回到一个没有变量赋值的调用,然后它将永远返回到它自己。您可以删除返回。tk.Label
继承了,那么为什么不对根窗口也这样做呢?padx
和pady
来确定小部件之间的间距。参见下面的返工示例。如果你有任何问题,请告诉我。
import tkinter as tk
import datetime as dt
import random
import time
phrases = [" I never had a policy; I have just tried to do my very best each and every day. -- Abraham Lincoln",
" There are some things you learn best in calm, and some in storm. -- Willa Cather",
" If a man does his best, what else is there? -- George S. Patton"]
class Clock(tk.Label):
""" Class that contains the clock widget and clock refresh """
def __init__(self, parent=None, seconds=True, colon=False):
"""
Create and place the clock widget into the parent element
It's an ordinary Label element with two additional features.
"""
tk.Label.__init__(self, parent, width=11)
self.display_seconds = seconds
self.time = None
if colon:
self.blink_colon()
self.tick()
def tick(self):
""" Updates the display clock every 200 milliseconds """
if self.display_seconds:
new_time = time.strftime('%I:%M:%S %p')
else:
new_time = time.strftime('%I:%M:%S %p').lstrip('0')
print(new_time)
if self.time is not None:
if new_time != self.time:
self.time = new_time
self.display_time = self.time
self.config(text=self.display_time)
else:
self.time = new_time
self.after(1000, self.tick)
def blink_colon(self):
""" Blink the colon every second """
if ':' in self.display_time:
self.display_time = self.display_time.replace(':', ' ')
else:
self.display_time = self.display_time.replace(' ', ':', 1)
self.config(text=self.display_time)
self.after(1000, self.blink_colon)
class App(tk.Tk):
def __init__(self):
super().__init__()
self.configure(bg="black")
self.wm_attributes('-fullscreen', 'true')
tk.Button(self, text="Quit", bg="black", fg="white", command=self.quit).pack()
clock1 = Clock(self)
clock1.configure(bg='black', fg='white', font=("helvetica", 60))
w = tk.Label(self, text=f"{dt.datetime.now():%a, %b %d %Y}",
fg="white", bg="black", font=("helvetica", 30), width=16)
clock1.pack(anchor='nw', pady=(25, 0))
w.pack(anchor='nw', pady=(0, 30))
self.e = tk.Label(self, fg="white", bg="black", font=("helvetica", 17))
self.phrase_refresh()
self.e.pack(anchor='nw')
def phrase_refresh(self):
new_phrase = random.choice(phrases)
self.e.configure(text=new_phrase, wrap=650)
self.after(86400, self.phrase_refresh)
App().mainloop()
最后,我不确定你是否想让计时器在左上角。从你的全屏判断,我猜你想要以它为中心。为此,我更倾向于使用grid()
over pack()
,因为网格允许我们为行和列设置权重,从而使IMO更容易对所有内容进行居中。
参见此示例:
import tkinter as tk
import datetime as dt
import random
import time
phrases = ["I never had a policy; I have just tried to do my very best each and every day. -- Abraham Lincoln",
"There are some things you learn best in calm, and some in storm. -- Willa Cather",
"If a man does his best, what else is there? -- George S. Patton"]
class Clock(tk.Label):
""" Class that contains the clock widget and clock refresh """
def __init__(self, parent=None, seconds=True, colon=False):
"""
Create and place the clock widget into the parent element
It's an ordinary Label element with two additional features.
"""
tk.Label.__init__(self, parent, width=11)
self.display_seconds = seconds
self.time = None
if colon:
self.blink_colon()
self.tick()
def tick(self):
""" Updates the display clock every 200 milliseconds """
if self.display_seconds:
new_time = time.strftime('%I:%M:%S %p')
else:
new_time = time.strftime('%I:%M:%S %p').lstrip('0')
print(new_time)
if self.time is not None:
if new_time != self.time:
self.time = new_time
self.display_time = self.time
self.config(text=self.display_time)
else:
self.time = new_time
self.after(1000, self.tick)
def blink_colon(self):
""" Blink the colon every second """
if ':' in self.display_time:
self.display_time = self.display_time.replace(':', ' ')
else:
self.display_time = self.display_time.replace(' ', ':', 1)
self.config(text=self.display_time)
self.after(1000, self.blink_colon)
class App(tk.Tk):
def __init__(self):
super().__init__()
self.configure(bg="black")
self.wm_attributes('-fullscreen', 'true')
self.columnconfigure(0, weight=1)
self.rowconfigure(1, weight=1)
tk.Button(self, text="Quit", bg="black", fg="white", command=self.quit).grid(row=0, column=0)
frame = tk.Frame(self, bg="black")
frame.grid(row=1, column=0)
clock1 = Clock(frame)
clock1.configure(bg='black', fg='white', font=("helvetica", 60))
w = tk.Label(frame, text=f"{dt.datetime.now():%a, %b %d %Y}",
fg="white", bg="black", font=("helvetica", 30), width=16)
clock1.grid(row=2, column=0, pady=(25, 0))
w.grid(row=3, column=0, pady=(0, 30))
self.e = tk.Label(frame, fg="white", bg="black", font=("helvetica", 17))
self.phrase_refresh()
self.e.grid(row=6, column=0)
def phrase_refresh(self):
new_phrase = random.choice(phrases)
self.e.configure(text=new_phrase, wrap=650)
self.after(86400, self.phrase_refresh)
App().mainloop()
https://codereview.stackexchange.com/questions/236257
复制相似问题