Python 秒表示例 - 同时启动所有类实例?

标签 python tkinter

在此示例中,如何同时启动所有 4 个秒表?

这个示例代码已有 12 多年历史,但它是我通过 Google 找到的最好的秒表示例。您可以看到我正在使用该类的 4 个实例。我需要能够同时启动所有实例。 Tinker 按钮不允许调用多个函数。即使确实如此,它也将是一个函数在下一个函数之前,因此从技术上讲,它们不会全部同时启动。

我需要在不同的时间停止每个秒表,但这很容易,只需调用类中的每个 Stop 函数即可。但我不知道如何同时启动它们。

from Tkinter import *
import time

class StopWatch(Frame):
    """ Implements a stop watch frame widget. """
    def __init__(self, parent=None, **kw):
        Frame.__init__(self, parent, kw)
        self._start = 0.0
        self._elapsedtime = 0.0
        self._running = 0
        self.timestr = StringVar()
        self.makeWidgets()

    def makeWidgets(self):
        """ Make the time labels. """
        l = Label(self, textvariable=self.timestr)

        l.pack(fill=X, expand=NO, pady=2, padx=2)


        self._setTime(self._elapsedtime)

    def _update(self):
        """ Update the label with elapsed time. """
        self._elapsedtime = time.time() - self._start
        self._setTime(self._elapsedtime)
        self._timer = self.after(50, self._update)

    def _setTime(self, elap):
        """ Set the time string to Minutes:Seconds:Hundreths """
        minutes = int(elap/60)
        seconds = int(elap - minutes*60.0)
        hseconds = int((elap - minutes*60.0 - seconds)*100)
        self.timestr.set('%02d:%02d:%02d' % (minutes, seconds, hseconds))

    def Start(self):
        global sw2
        """ Start the stopwatch, ignore if running. """
        if not self._running:
            self._start = time.time() - self._elapsedtime
            self._update()
            self._running = 1


    def Stop(self):
        """ Stop the stopwatch, ignore if stopped. """
        if self._running:
            self.after_cancel(self._timer)
            self._elapsedtime = time.time() - self._start
            self._setTime(self._elapsedtime)
            self._running = 0

    def Reset(self):
        """ Reset the stopwatch. """
        self._start = time.time()
        self._elapsedtime = 0.0
        self._setTime(self._elapsedtime)


def main():


    root = Tk()
    sw1 = StopWatch(root)
    sw1.pack(side=TOP)

    sw2 = StopWatch(root)
    sw2.pack(side=TOP)

    sw3 = StopWatch(root)
    sw3.pack(side=TOP)

    sw4 = StopWatch(root)
    sw4.pack(side=TOP)

    Button(root, text='Start', command=sw1.Start).pack(side=LEFT)
    Button(root, text='Stop', command=sw1.Stop).pack(side=LEFT)
    Button(root, text='Reset', command=sw1.Reset).pack(side=LEFT)
    Button(root, text='Quit', command=root.quit).pack(side=LEFT)

    root.mainloop()

if __name__ == '__main__':
    main()

最佳答案

以下程序可能接近您想要的。请注意,由于启动和停止秒表需要时间,因此您可能会发现它们显示的时间存在细微差异。

#! /usr/bin/env python3
import tkinter
import time

class StopWatch(tkinter.Frame):

    @classmethod
    def main(cls):
        tkinter.NoDefaultRoot()
        root = tkinter.Tk()
        root.title('Stop Watch')
        root.resizable(True, False)
        root.grid_columnconfigure(0, weight=1)
        padding = dict(padx=5, pady=5)
        widget = StopWatch(root, **padding)
        widget.grid(sticky=tkinter.NSEW, **padding)
        root.mainloop()

    def __init__(self, master=None, cnf={}, **kw):
        padding = dict(padx=kw.pop('padx', 5), pady=kw.pop('pady', 5))
        super().__init__(master, cnf, **kw)
        self.grid_columnconfigure(1, weight=1)
        self.grid_rowconfigure(1, weight=1)
        self.__total = 0
        self.__label = tkinter.Label(self, text='Total Time:')
        self.__time = tkinter.StringVar(self, '0.000000')
        self.__display = tkinter.Label(self, textvariable=self.__time)
        self.__button = tkinter.Button(self, text='Start', command=self.click)
        self.__label.grid(row=0, column=0, sticky=tkinter.E, **padding)
        self.__display.grid(row=0, column=1, sticky=tkinter.EW, **padding)
        self.__button.grid(row=1, column=0, columnspan=2,
                           sticky=tkinter.NSEW, **padding)

    def click(self):
        if self.__button['text'] == 'Start':
            self.__button['text'] = 'Stop'
            self.__start = time.clock()
            self.__counter = self.after_idle(self.__update)
        else:
            self.__button['text'] = 'Start'
            self.after_cancel(self.__counter)

    def __update(self):
        now = time.clock()
        diff = now - self.__start
        self.__start = now
        self.__total += diff
        self.__time.set('{:.6f}'.format(self.__total))
        self.__counter = self.after_idle(self.__update)

class ManyStopWatch(tkinter.Tk):

    def __init__(self, count):
        super().__init__()
        self.title('Stopwatches')
        padding = dict(padx=5, pady=5)
        tkinter.Button(self, text='Toggle All', command=self.click).grid(
            sticky=tkinter.NSEW, **padding)
        for _ in range(count):
            StopWatch(self, **padding).grid(sticky=tkinter.NSEW, **padding)

    def click(self):
        for child in self.children.values():
            if isinstance(child, StopWatch):
                child.click()

if __name__ == '__main__':
    ManyStopWatch(4).mainloop()

关于Python 秒表示例 - 同时启动所有类实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28567530/

相关文章:

python 数学公式模块/框架?

python - Django 上传表单,附加字段导致错误

python - 如何根据 Python 中的 OpenAPI3 规范验证 HTTP 请求?

python - Python中有序子集的高效枚举

Python Multiprocessing Process.start() 等待进程启动

python - 为什么 Tkinter 可以是程序化的,而 PyQt 只能与 OO 范式一起使用?

python - tkinter:更改特定菜单项的前景色

python - 当 mysql 和用户输入不相同时,标签提供错误的动态名称

python - 如何获取调用事件的小部件的 ID (Tkinter)

python - 在 Tkinter 中动态改变 Canvas 的滚动区域