当我将 update() 与 tkinter 一起使用时,我的标签会写入另一行,而不是重写相同的文本

发布于 2024-12-06 22:50:18 字数 197 浏览 0 评论 0原文

当我使用 tkinter 调用 update() 方法而不是重写标签时,它只是在上一次调用下写入标签。我想重写前一行。

例如:

root=Tk()
while True:
    w=Label(root, text = (price, time))
    w.pack()
    root.update()

When I call the update() method using tkinter instead of rewriting the label it just writes the label under the previous call. I would like for this to rewrite over the previous line.

For Example:

root=Tk()
while True:
    w=Label(root, text = (price, time))
    w.pack()
    root.update()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

风吹雪碎 2024-12-13 22:50:18

您的问题很简单:当您执行 while True 时,您会创建一个无限循环。该循环中的代码将一直运行,直到您强制程序退出。在该循环中,您创建一个标签。因此,您将创建无限数量的标签。

如果您想定期更新标签,请利用已经运行的无限循环 - 事件循环。您可以使用 after 来安排将来调用的函数。该函数可以重新安排自身再次运行,保证它将运行直到程序退出。

这是一个简单的例子:

import Tkinter as tk
import time

class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.clock = tk.Label(self, text="")
        self.clock.pack()

        # start the clock "ticking"
        self.update_clock()

    def update_clock(self):
        now = time.strftime("%H:%M:%S" , time.gmtime())
        self.clock.configure(text=now)
        # call this function again in one second
        self.after(1000, self.update_clock)

if __name__== "__main__":
    app = SampleApp()
    app.mainloop()

Your problem is simply this: when you do while True, you create an infinite loop. The code in that loop will run until you force the program to exit. In that loop you create a label. Thus, you will create an infinite number of labels.

If you want to update a label on a regular basis, take advantage of the already running infinite loop - the event loop. You can use after to schedule a function to be called in the future. That function can reschedule itself to run again, guaranteeing it will run until the program quits.

Here's a simple example:

import Tkinter as tk
import time

class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.clock = tk.Label(self, text="")
        self.clock.pack()

        # start the clock "ticking"
        self.update_clock()

    def update_clock(self):
        now = time.strftime("%H:%M:%S" , time.gmtime())
        self.clock.configure(text=now)
        # call this function again in one second
        self.after(1000, self.update_clock)

if __name__== "__main__":
    app = SampleApp()
    app.mainloop()
你没皮卡萌 2024-12-13 22:50:18

不。

我怀疑,在没有亲眼目睹的情况下,wDroter 编写的代码中至少存在一些混乱之处。一般来说,在结构良好的 Tkinter 代码中根本没有必要使用 update() 。下面是一个小示例,说明了标签文本的更新:

import Tkinter
import time

def update_the_label():
    updated_text = time.strftime("The GM time now is %H:%M:%S.", time.gmtime())
    w.configure(text = updated_text)

root = Tkinter.Tk()
w = Tkinter.Label(root, text = "Hello, world!")
b = Tkinter.Button(root, text = "Update the label", command = update_the_label)
w.pack()
b.pack()

root.mainloop()

运行此命令。按下按钮。每次执行此操作(只要您的推送至少相差一秒),您都会看到文本更新。

No.

I suspect, without having seen it, that there are at least a couple of confusions in the code wDroter has written. In general, it is NOT necessary in well-structured Tkinter code to use update() at all. Here's a small example that illustrates updates to the text of a Label:

import Tkinter
import time

def update_the_label():
    updated_text = time.strftime("The GM time now is %H:%M:%S.", time.gmtime())
    w.configure(text = updated_text)

root = Tkinter.Tk()
w = Tkinter.Label(root, text = "Hello, world!")
b = Tkinter.Button(root, text = "Update the label", command = update_the_label)
w.pack()
b.pack()

root.mainloop()

Run this. Push the button. Each time you do so (as long as your pushes differ by at least a second), you'll see the text update.

烦人精 2024-12-13 22:50:18

你想使用 .configure 安装

while True:
    w.Configure(text = (price, time))
    root.update()

you want to use .configure insted

while True:
    w.Configure(text = (price, time))
    root.update()
微暖i 2024-12-13 22:50:18

而不是
w.pack()
你可以写
tkinter 中的w.grid(row=0, column=0)

pack() 通常将内容打包在单行/列中。它将东西沿着盒子的两侧排列。然而,grid() 具有更多类似表格的结构。因此,当您编写 row=0column=0 时,它别无选择,只能替换前一个(如果存在)。因为您提供了一个非常具体的位置,而不是仅仅将其推到窗口(这是 pack() 所做的)

instead of
w.pack()
you can write
w.grid(row=0, column=0)

pack() in tkinter usually packs things in a single row/column. It lays things out along the sides of a box. Whereas, grid() has more of a table like structure. So when you write row=0 and column=0, it has no choice but to replace the previous if it exists. Because you have provided a very specific position instead of just pushing it to the window (which is hat pack() does)

埋葬我深情 2024-12-13 22:50:18

BadRoot 类应该演示您遇到的问题。您可以注释掉对类的调用,以使用完整的工作示例进行验证。如果您按照编写的方式运行代码,它将更新 GoodRoot 类中的标签。注释掉的第一行显示了用于更改标签中文本的替代语法。

from tkinter import Tk, Label
from time import sleep
from random import random

class BadRoot(Tk):

    def __init__(self, price, time):
        super().__init__()
        self.labels = []
        while True:
            self.labels.append(Label(self, text=(price, time)))
            self.labels[-1].pack()
            self.update()
            sleep(1)

class GoodRoot(Tk):

    def __init__(self, callback):
        super().__init__()
        self.label = Label(self, text=str(callback()))
        self.label.pack()
        while True:
##            self.label['text'] = str(callback())
            self.label.configure(text=str(callback()))
            self.update()
            sleep(1)

if __name__ == '__main__':
##    BadRoot('$1.38', '2:37 PM')
    GoodRoot(random)

原始代码的问题是每次循环都会创建一个新标签并将其打包到界面中。您真正想要做的只是编辑标签显示的文本,而不是用新标签替换标签。还有其他方法可以执行此操作,但此方法应该适合您。

The BadRoot class should demonstrate the problem that you are having. You can comment out the call to the class to verify with a complete, working example. If you run the code as written, it will update the label in the GoodRoot class. The first line that is commented out shows an alternative syntax for changing the text in your label.

from tkinter import Tk, Label
from time import sleep
from random import random

class BadRoot(Tk):

    def __init__(self, price, time):
        super().__init__()
        self.labels = []
        while True:
            self.labels.append(Label(self, text=(price, time)))
            self.labels[-1].pack()
            self.update()
            sleep(1)

class GoodRoot(Tk):

    def __init__(self, callback):
        super().__init__()
        self.label = Label(self, text=str(callback()))
        self.label.pack()
        while True:
##            self.label['text'] = str(callback())
            self.label.configure(text=str(callback()))
            self.update()
            sleep(1)

if __name__ == '__main__':
##    BadRoot('$1.38', '2:37 PM')
    GoodRoot(random)

The problem with your original code is that a new label is created and packed into the interface each time through the loop. What you actually want to do is just edit the text being displayed by the label instead replacing the label with a new one. There are others ways of doing this, but this method should work for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文