Tkinter中的活动指示器?

3
每个操作系统都有一个活动指示器。OS X和iOS有一朵花,每个花瓣都会以圆形模式亮起并逐渐消失。Windows有一个旋转的蓝色圆盘。Android有一个灰色的圆盘(我认为它也可以是其他颜色 - 我不常用Android)。
在Tkinter中使用这些图标的最佳方法是什么?是否有一些内置的小部件可以提供此功能?或者是否有一个变量可以让Image小部件显示该图标(并进行动画处理)?
我知道Tkinter提供了一个进度条,其中有一个不确定的模式。但我不想使用它 - 我需要适合小正方形区域的东西,而不是长方形区域。第一段描述的活动指示器将是完美的选择。
或者我的最佳选择是自己制作画布动画?

不是答案,但也许这可以帮助MacOS https://gist.github.com/pudquick/f7cefd0d4320e0b648da - Noel Segura Meraz
你可能需要使用 CanvasLabel 显示图像,但是你需要自己制作动画(使用 root.after)。 - furas
@NoelSegura - 嗯,那需要依赖于 AppKit/Cocoa。有没有办法将 AppKit 的小部件和 Tkinter 的小部件混合使用?我曾经认为这是不可能的。 - ArtOfWarfare
是的,你说得对,Appkit会生成一个新窗口,也许有一种方法可以获取动画资源,但此时我不知道与在画布中下载gif并自己制作动画相比哪种更好。 - Noel Segura Meraz
1个回答

0

这应该足够你想要做的事情了。然后,我会创建自己的动画或从互联网逐帧下载要显示的图像。Canvas更多用于与用户的交互,这就是为什么我使用标签来显示图像的原因...

import tkinter as tk

class Activity(tk.Label):
    def __init__(self, master = None, delay = 1000, cnf = {}, **kw):
        self._taskID = None
        self.delay = delay
        return super().__init__(master, cnf, **kw)

    # starts the animation
    def start(self):
        self.after(0, self._loop)

    # calls its self after a specific <delay>
    def _loop(self):
        currentText = self["text"] + "."

        if currentText == "....":
            currentText = ""

        self["text"] = currentText

        self._taskID = self.after(self.delay, self._loop)

    # stopps the loop method calling its self
    def stop(self):
        self.after_cancel(self._taskID)
        # Depends if you want to destroy the widget after the loop has stopped
        self.destroy()


class AcitivityImage(Activity):
    def __init__(self, imagename, frames, filetype, master = None, delay = 1000, cnf = {}, **kw):
        self._frames = []
        self._index = 0
        for i in range(frames):
            self._frames.append(tk.PhotoImage(file = imagename+str(i)+'.'+str(filetype)))

        return super().__init__(master, delay, cnf, **kw)

    def _loop(self):
        self["image"] = self._frames[self._index]

        # add one to index if the index is less then the amount of frames
        self._index = (self._index + 1 )% len(self._frames)

        self._taskID = self.after(self.delay, self._loop)


root = tk.Tk()
root.geometry("500x500")

# create a activity image widget
#root.b = AcitivityImage("activity", 3, "png", root)
#root.b.pack()

# create the activity widget
root.a = Activity(root, 500, bg = "yellow")
root.a.pack()

# start the loop
root.a.start()
#root.b.start()

# stop the activity loop after 7 seconds
root.after(7000, root.a.stop)
#root.after(8000, root.b.stop)

root.mainloop().

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接