使用Python和Gtk进行倒数计时,出现timeout_add

时间:2018-07-05 20:47:34

标签: python gtk3 pygobject


我正在尝试制作锻炼应用程序,因此我必须计算每次俯卧撑或显示侧板的倒数。为此,我尝试使用 GObject.timeout_add ,但它似乎不起作用,就像我认为的那样。
在当前情况下,会话的所有练习都以适当的顺序同时运行,而不是一次运行。 我当然缺少一些东西,通过我的网络搜索,我仍然没有找到它。
这是我的代码:

#!/usr/bin/python
"""
Work out app to keep track of your progression through the session
"""

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GObject
from Programms import *
from time import sleep


def time_hours(t):
    return t // 3600


def time_minutes(t):
    return (t % 3600) // 60


def time_seconds(t):
    return int((t % 3600) % 60)


def time_format(t):
    hours = double_digit(time_hours(t))
    minutes = double_digit(time_minutes(t))
    seconds = double_digit(time_seconds(t))
    return "{}:{}:{}".format(hours, minutes, seconds)


def double_digit(t):
    if t == 0:
        return "00"
    elif t < 10:
        return "0{}".format(t)
    return t


class StartingLine:
    """
    Gtk
    """
    def __init__(self):
        # main window
        self.window = Gtk.Window()
        self.window.set_title("Work out !")
        self.window.set_size_request(200, 200)
        self.window.connect('destroy', lambda x: Gtk.main_quit())

        # start button
        self.button = Gtk.Button("Start")
        self.button.connect('clicked', self.start_work_out)

        self.window.add(self.button)

        self.window.show_all()

    def start_work_out(self, widget):
        self.window.hide()
        work = Two
        duration = work.duration
        for exo in work.exercises:
            Instructor(exo, duration)


class Instructor:
    """
    Gtk
    """
    def __init__(self, exo, duration):
        # main window
        self.window = Gtk.Window()
        self.window.set_title("Work out !")
        self.window.set_size_request(200, 200)
        self.window.connect("destroy", lambda x: Gtk.main_quit())

        # timer
        self.current_time = 0
        self.counter = 0
        self.timer_label = Gtk.Label(time_format(self.counter))

        # exercise
        self.current_exercise = Gtk.Label(exo.name)

        # overall progression
        self.bar = Gtk.ProgressBar.new()

        # hierarchy
        grid = Gtk.Grid()
        grid.attach(self.timer_label, 1, 0, 1, 1)
        grid.attach(self.current_exercise, 1, 1, 1, 1)
        grid.attach(self.bar, 1, 2, 1, 1)
        self.window.add(grid)

        # display
        self.window.show_all()

        if exo.type == ExoType.Reps:
            print('exercise : ', exo.name)
            self.counter = 0
            self.timer_label.set_label(str(self.counter))
            rep_id = GObject.timeout_add(1000*exo.in_between, self.display_rep, exo, duration)
            print("rep ID : ", rep_id)
        elif exo.type == ExoType.Timer:
            self.counter = exo.number
            self.timer_label.set_label(time_format(self.counter))
            time_id = GObject.timeout_add(1000*exo.in_between, self.display_timer, exo, duration)
            print("time ID : ", time_id)

    def display_rep(self, exo, duration):
        print("current time : ", self.current_time)
        print("current exercise : ", exo.name)
        print("rep : ", self.counter)
        self.counter += 1
        self.current_time += exo.in_between
        self.timer_label.set_label(str(self.counter))  # update counter
        self.current_exercise.set_label(exo.name)  # update exercise name
        self.bar.set_fraction(self.current_time/duration)  # update progression bar
        return self.counter < exo.number

    def display_timer(self, exo, duration):
        print("current time : ", self.current_time)
        print("current exercise : ", exo.name)
        print("timer : ", self.counter)
        self.counter -= 1
        self.current_time += exo.in_between
        self.timer_label.set_label(time_format(self.counter))  # update counter
        self.current_exercise.set_label(exo.name)  # update name
        self.bar.set_fraction(self.current_time/duration)  # update progression bar
        return self.counter > 0


if __name__ == "__main__":
    StartingLine()
    Gtk.main()

在这段代码中,我使用了两种类型:

#!/usr/bin/python

"""
define class exercise and class session
"""


class Exercise:
    def __init__(self, name, typo, unilateral, number, preparation=0, in_between=1):
        """
        :param name: name of the exercise
        :param typo: either timer or reps
        :param number: either a time in seconds or a a number of reps
        :param preparation: time allocated to prepare the exercise, to put yourself in position
        :param in_between: time between reps. 1s by default.
        """
        self.name = name
        self.type = typo
        self.unilateral = unilateral
        self.number = number
        self.prep = preparation
        self.in_between = in_between


class ExoType(enumerate):
    Reps = 0
    Timer = 1


class Session:
    def __init__(self, name, exercises):
        self.name = name
        self.exercises = exercises
        self.duration = time_length(exercises)


def time_length(exercises):
    t = 0
    for exo in exercises:
        if exo.type == ExoType.Timer:
            t += exo.number
        elif exo.type == ExoType.Reps:
            t += exo.number*exo.in_between
        else:
            print("Error : Session duration")
    return t

第一次在这里问一个问题,请告诉我是否做错了。

1 个答案:

答案 0 :(得分:0)

rep_id = GObject.timeout_add(1000*exo.in_between, self.display_rep, exo, duration)

timeout_add告诉您Mainloop每function秒调用一次n

for exo in work.exercises:
    Instructor(exo, duration)

在这里,您将每个练习都添加到mainloop中,从而导致同时运行,因为您只需创建一次mainloop。

有几种解决方案,我认为它们都不包含main_iteration_do

  1. 重新组织事情,以便1个练习可以运行它自己的主循环。
  2. 一个练习结束并在其处理程序中开始另一个练习时发出信号。