Python 如何将标签小部件彼此相邻放置?
我正在创建一个简单的GUI程序来测量某个事件的时间。一切正常,但有一件事让我感到困扰——所有标签小部件都在“闪烁”(由于被创建),因此我想重新构造代码,以便我有两个标签组——其中一个标签组会不断显示,另一个标签组(实际测量时间)会闪烁。问题是,当我尝试将一个标签拆分为两个较小的标签时,我无法使它正好位于另一个标签的旁边,因此看起来如下: 这是我的原始工作代码:Python 如何将标签小部件彼此相邻放置?,python,tkinter,Python,Tkinter,我正在创建一个简单的GUI程序来测量某个事件的时间。一切正常,但有一件事让我感到困扰——所有标签小部件都在“闪烁”(由于被创建),因此我想重新构造代码,以便我有两个标签组——其中一个标签组会不断显示,另一个标签组(实际测量时间)会闪烁。问题是,当我尝试将一个标签拆分为两个较小的标签时,我无法使它正好位于另一个标签的旁边,因此看起来如下: 这是我的原始工作代码: # str8.py # Program to count time from a certain event from tkin
# str8.py
# Program to count time from a certain event
from tkinter import *
from datetime import *
from threading import *
def display():
event, today, str8, seconds, minutes, hours, days, weeks, years = calc()
Label(root,
text = "You have been STR8 for:\n",
font = "Verdana 8 bold").grid(row = 0, sticky = W)
Label(root,
text = "Years: "
+ str(round(years, 2)),
font = "Verdana 8").grid(row = 1, sticky = W)
Label(root,
text = "Weeks: "
+ str(round(weeks, 2)),
font = "Verdana 8").grid(row = 2, sticky = W)
Label(root,
text = "Days: "
+ str(round(days, 2)),
font = "Verdana 8").grid(row = 3, sticky = W)
Label(root,
text = "Hours: "
+ str(round(hours, 2)),
font = "Verdana 8").grid(row = 4, sticky = W)
Label(root,
text = "Minutes: "
+ str(round(minutes, 2)),
font = "Verdana 8").grid(row = 5, sticky = W)
Label(root,
text = "Seconds: "
+ str(round(str8.total_seconds())),
font = "Verdana 8").grid(row = 6, sticky = W)
Button(root,
text = "EXIT",
font = "Verdana 8",
height = 1,
width = 19,
command = quit).grid(row = 7)
def calc():
event = datetime(2017, 4, 4, 0, 0, 0)
today = datetime.now()
str8 = today - event
seconds = str8.total_seconds()
minutes = str8.total_seconds() / 60
hours = minutes / 60
days = hours / 24
weeks = days / 7
years = weeks / 52
return event, today, str8, seconds, minutes, hours, days, weeks, years
def print_it():
t = Timer(1.0, print_it)
calc()
try:
display()
except RuntimeError:
pass
else:
t.start()
def quit():
root.destroy()
if __name__ == '__main__':
root = Tk()
root.title("STR8")
root.resizable(width = False, height = False)
print_it()
root.mainloop()
…在我尝试拆分其中一个之前:
Label(root,
text = "Years: ",
font = "Verdana 8").grid(row = 1, sticky = W)
Label(root,
text = str(round(years, 2)),
font = "Verdana 8").grid(row = 1, column = 1, sticky = W)
然后,我会将所有不断显示的标签放入create_widgets()函数中,并将其他标签留在display()函数中
我使用的是Python3.5。TKinter有一个名为DoubleVar
,它允许您创建一个变量,可以用来更新标签小部件。使用此方法,而不是对标签使用text=
,您可以使用textvariable=
引用您创建的变量,并且Tk知道在变量更改值时更新标签(尽管应该注意,有其他方法可以实现更新标签,我在这里不详细介绍)
在下面的代码中,我们每个时间单位创建两个文本标签-一个用于告诉用户值与什么相关,另一个用于实际显示值。为了简单起见,我通过一本字典来做这件事
然后我们第一次调用increment
,它设置所有相关值。完成此操作后,我们使用self.After(1000,self.increment)
在1000毫秒=1秒后运行增量过程
# str8.py
# Program to count time from a certain event
from tkinter import *
from datetime import *
class App(Frame):
def __init__(self, *args, **kwargs):
Frame.__init__(self, *args, **kwargs)
self.grid(sticky=N + W + E + S)
Label(self, text='You have been STR8 for:', font="Verdana 8 bold").grid(row=0, sticky=W)
self.counters = dict()
measurements = ['Seconds', 'Minutes', 'Hours', 'Days', 'Weeks', 'Years']
for i, measurement in enumerate(measurements):
self.counters[measurement] = DoubleVar()
Label(self, text=measurement, font='Verdana 8').grid(row=i+1, column=0, sticky=W)
Label(self, textvariable=self.counters[measurement], font='Verdana 8').grid(row=i + 1, column=1, sticky=E)
self.counters[measurement].set(0)
Button(self,
text="EXIT",
font="Verdana 8",
height=1,
width=19,
command=quit).grid(row=7, column=0)
self.increment()
def increment(self):
event = datetime(2017, 4, 4, 0, 0, 0)
today = datetime.now()
str8 = today - event
self.counters['Seconds'].set(round(str8.total_seconds(), 2))
self.counters['Minutes'].set(round(str8.total_seconds()/60, 2))
self.counters['Hours'].set(round(str8.total_seconds() / 3600, 2))
self.counters['Days'].set(round(str8.total_seconds() / (3600 * 24), 2))
self.counters['Weeks'].set(round(str8.total_seconds() / (3600 * 24 * 7), 2))
self.counters['Years'].set(round(str8.total_seconds() / (3600 * 24 * 7 * 52), 2))
self.after(1000, self.increment)
if __name__ == '__main__':
root = Tk()
app = App(root)
root.title("STR8")
root.resizable(width=False, height=False)
app.mainloop()
这将生成一个如下所示的窗口:
并且应该每秒钟更新一次而不闪烁。每次更新时,您都会重新绘制每个小部件-这真的没有必要。您能给我建议一个替代解决方案吗,我还是个新手?您是否知道不需要使用
DoubleVar
(或任何其他tkinter变量)来更新标签?你的回答似乎暗示这是唯一的办法。@BryanOakley通过.config
?@BryanOakley重新措辞,试图让人更清楚地知道,这不是唯一的办法——恰好是我想到的办法。是否有任何理由排除使用另一种方法的偏好?我不喜欢使用变量,因为它会向我的代码中添加需要管理的额外对象。更新标签需要有变量或没有变量的函数调用,那么为什么要增加变量的开销呢?@asongtoruin我感谢您在不闪烁的情况下每秒钟更新一次标签,但是现在我的GUI还有其他问题。我希望标签彼此相邻,或者一个标签,例如,年份:0.0