Build a Time Tracking App with Tkinter and Pygame

Building a Time Tracking App with Tkinter and Pygame in Python

Creating a graphical user interface (GUI) for a time tracking app in Python can be accomplished using various libraries. Two popular choices are Tkinter, which is widely used for standard applications, and Pygame, which is generally utilized for game development but can also be adapted for other types of interactive applications. This article provides a comprehensive guide on how to use both to create a functional time tracking application.

Using Tkinter to Create a Time Tracking App

Tkinter is the standard GUI toolkit for Python. It provides a powerful object-oriented interface and is simple to learn and use.

Step 1: Setup

Before starting, make sure Python and Tkinter are installed. Tkinter is included with Python by default in most installations.

Step 2: Create the Main Window

Begin by importing Tkinter and setting up the main application window:

<span>import</span> <span>tkinter</span> <span>as</span> <span>tk</span>
<span>from</span> <span>tkinter</span> <span>import</span> <span>ttk</span>
<span>root</span> <span>=</span> <span>tk</span><span>.</span><span>Tk</span><span>()</span>
<span>root</span><span>.</span><span>title</span><span>(</span><span>"</span><span>Time Tracker</span><span>"</span><span>)</span>
<span>import</span> <span>tkinter</span> <span>as</span> <span>tk</span>
<span>from</span> <span>tkinter</span> <span>import</span> <span>ttk</span>

<span>root</span> <span>=</span> <span>tk</span><span>.</span><span>Tk</span><span>()</span>
<span>root</span><span>.</span><span>title</span><span>(</span><span>"</span><span>Time Tracker</span><span>"</span><span>)</span>
import tkinter as tk from tkinter import ttk root = tk.Tk() root.title("Time Tracker")

Enter fullscreen mode Exit fullscreen mode

Step 3: Design the GUI

Add essential GUI components. For a time tracker, you need a display for the time and buttons to control it:

<span>timer_label</span> <span>=</span> <span>ttk</span><span>.</span><span>Label</span><span>(</span><span>root</span><span>,</span> <span>text</span><span>=</span><span>"</span><span>00:00:00</span><span>"</span><span>,</span> <span>font</span><span>=</span><span>(</span><span>"</span><span>Segoe UI</span><span>"</span><span>,</span> <span>30</span><span>))</span>
<span>timer_label</span><span>.</span><span>pack</span><span>(</span><span>pady</span><span>=</span><span>20</span><span>)</span>
<span>start_button</span> <span>=</span> <span>ttk</span><span>.</span><span>Button</span><span>(</span><span>root</span><span>,</span> <span>text</span><span>=</span><span>"</span><span>Start</span><span>"</span><span>,</span> <span>command</span><span>=</span><span>lambda</span><span>:</span> <span>start_timer</span><span>())</span>
<span>start_button</span><span>.</span><span>pack</span><span>(</span><span>side</span><span>=</span><span>tk</span><span>.</span><span>LEFT</span><span>,</span> <span>padx</span><span>=</span><span>20</span><span>)</span>
<span>stop_button</span> <span>=</span> <span>ttk</span><span>.</span><span>Button</span><span>(</span><span>root</span><span>,</span> <span>text</span><span>=</span><span>"</span><span>Stop</span><span>"</span><span>,</span> <span>command</span><span>=</span><span>lambda</span><span>:</span> <span>stop_timer</span><span>())</span>
<span>stop_button</span><span>.</span><span>pack</span><span>(</span><span>side</span><span>=</span><span>tk</span><span>.</span><span>RIGHT</span><span>,</span> <span>padx</span><span>=</span><span>20</span><span>)</span>
<span>timer_label</span> <span>=</span> <span>ttk</span><span>.</span><span>Label</span><span>(</span><span>root</span><span>,</span> <span>text</span><span>=</span><span>"</span><span>00:00:00</span><span>"</span><span>,</span> <span>font</span><span>=</span><span>(</span><span>"</span><span>Segoe UI</span><span>"</span><span>,</span> <span>30</span><span>))</span>
<span>timer_label</span><span>.</span><span>pack</span><span>(</span><span>pady</span><span>=</span><span>20</span><span>)</span>

<span>start_button</span> <span>=</span> <span>ttk</span><span>.</span><span>Button</span><span>(</span><span>root</span><span>,</span> <span>text</span><span>=</span><span>"</span><span>Start</span><span>"</span><span>,</span> <span>command</span><span>=</span><span>lambda</span><span>:</span> <span>start_timer</span><span>())</span>
<span>start_button</span><span>.</span><span>pack</span><span>(</span><span>side</span><span>=</span><span>tk</span><span>.</span><span>LEFT</span><span>,</span> <span>padx</span><span>=</span><span>20</span><span>)</span>

<span>stop_button</span> <span>=</span> <span>ttk</span><span>.</span><span>Button</span><span>(</span><span>root</span><span>,</span> <span>text</span><span>=</span><span>"</span><span>Stop</span><span>"</span><span>,</span> <span>command</span><span>=</span><span>lambda</span><span>:</span> <span>stop_timer</span><span>())</span>
<span>stop_button</span><span>.</span><span>pack</span><span>(</span><span>side</span><span>=</span><span>tk</span><span>.</span><span>RIGHT</span><span>,</span> <span>padx</span><span>=</span><span>20</span><span>)</span>
timer_label = ttk.Label(root, text="00:00:00", font=("Segoe UI", 30)) timer_label.pack(pady=20) start_button = ttk.Button(root, text="Start", command=lambda: start_timer()) start_button.pack(side=tk.LEFT, padx=20) stop_button = ttk.Button(root, text="Stop", command=lambda: stop_timer()) stop_button.pack(side=tk.RIGHT, padx=20)

Enter fullscreen mode Exit fullscreen mode

Step 4: Add Functionality

Define the functions that will start, stop, and update the timer:

<span>running</span> <span>=</span> <span>False</span>
<span>start_time</span> <span>=</span> <span>0</span>
<span>def</span> <span>update_timer</span><span>():</span>
<span>if</span> <span>running</span><span>:</span>
<span>elapsed_time</span> <span>=</span> <span>time</span><span>.</span><span>time</span><span>()</span> <span>-</span> <span>start_time</span>
<span>minutes</span><span>,</span> <span>seconds</span> <span>=</span> <span>divmod</span><span>(</span><span>int</span><span>(</span><span>elapsed_time</span><span>),</span> <span>60</span><span>)</span>
<span>hours</span><span>,</span> <span>minutes</span> <span>=</span> <span>divmod</span><span>(</span><span>minutes</span><span>,</span> <span>60</span><span>)</span>
<span>timer_label</span><span>.</span><span>config</span><span>(</span><span>text</span><span>=</span><span>f</span><span>"</span><span>{</span><span>hours</span><span>:</span><span>02</span><span>}</span><span>:</span><span>{</span><span>minutes</span><span>:</span><span>02</span><span>}</span><span>:</span><span>{</span><span>seconds</span><span>:</span><span>02</span><span>}</span><span>"</span><span>)</span>
<span>root</span><span>.</span><span>after</span><span>(</span><span>1000</span><span>,</span> <span>update_timer</span><span>)</span>
<span>def</span> <span>start_timer</span><span>():</span>
<span>global</span> <span>running</span><span>,</span> <span>start_time</span>
<span>if</span> <span>not</span> <span>running</span><span>:</span>
<span>running</span> <span>=</span> <span>True</span>
<span>start_time</span> <span>=</span> <span>time</span><span>.</span><span>time</span><span>()</span>
<span>update_timer</span><span>()</span>
<span>def</span> <span>stop_timer</span><span>():</span>
<span>global</span> <span>running</span><span>,</span> <span>start_time</span>
<span>running</span> <span>=</span> <span>False</span>
<span>start_time</span> <span>=</span> <span>0</span>
<span>timer_label</span><span>.</span><span>config</span><span>(</span><span>text</span><span>=</span><span>"</span><span>00:00:00</span><span>"</span><span>)</span>
<span>running</span> <span>=</span> <span>False</span>
<span>start_time</span> <span>=</span> <span>0</span>

<span>def</span> <span>update_timer</span><span>():</span>
    <span>if</span> <span>running</span><span>:</span>
        <span>elapsed_time</span> <span>=</span> <span>time</span><span>.</span><span>time</span><span>()</span> <span>-</span> <span>start_time</span>
        <span>minutes</span><span>,</span> <span>seconds</span> <span>=</span> <span>divmod</span><span>(</span><span>int</span><span>(</span><span>elapsed_time</span><span>),</span> <span>60</span><span>)</span>
        <span>hours</span><span>,</span> <span>minutes</span> <span>=</span> <span>divmod</span><span>(</span><span>minutes</span><span>,</span> <span>60</span><span>)</span>
        <span>timer_label</span><span>.</span><span>config</span><span>(</span><span>text</span><span>=</span><span>f</span><span>"</span><span>{</span><span>hours</span><span>:</span><span>02</span><span>}</span><span>:</span><span>{</span><span>minutes</span><span>:</span><span>02</span><span>}</span><span>:</span><span>{</span><span>seconds</span><span>:</span><span>02</span><span>}</span><span>"</span><span>)</span>
        <span>root</span><span>.</span><span>after</span><span>(</span><span>1000</span><span>,</span> <span>update_timer</span><span>)</span>

<span>def</span> <span>start_timer</span><span>():</span>
    <span>global</span> <span>running</span><span>,</span> <span>start_time</span>
    <span>if</span> <span>not</span> <span>running</span><span>:</span>
        <span>running</span> <span>=</span> <span>True</span>
        <span>start_time</span> <span>=</span> <span>time</span><span>.</span><span>time</span><span>()</span>
        <span>update_timer</span><span>()</span>

<span>def</span> <span>stop_timer</span><span>():</span>
    <span>global</span> <span>running</span><span>,</span> <span>start_time</span>
    <span>running</span> <span>=</span> <span>False</span>
    <span>start_time</span> <span>=</span> <span>0</span>
    <span>timer_label</span><span>.</span><span>config</span><span>(</span><span>text</span><span>=</span><span>"</span><span>00:00:00</span><span>"</span><span>)</span>
running = False start_time = 0 def update_timer(): if running: elapsed_time = time.time() - start_time minutes, seconds = divmod(int(elapsed_time), 60) hours, minutes = divmod(minutes, 60) timer_label.config(text=f"{hours:02}:{minutes:02}:{seconds:02}") root.after(1000, update_timer) def start_timer(): global running, start_time if not running: running = True start_time = time.time() update_timer() def stop_timer(): global running, start_time running = False start_time = 0 timer_label.config(text="00:00:00")

Enter fullscreen mode Exit fullscreen mode

Step 5: Main Loop

Keep the window open and responsive:

<span>root</span><span>.</span><span>mainloop</span><span>()</span>
<span>root</span><span>.</span><span>mainloop</span><span>()</span>
root.mainloop()

Enter fullscreen mode Exit fullscreen mode

Using Pygame as an Alternative

Pygame offers more flexibility in terms of graphics and animations, making it a viable alternative for building a time tracking app, especially if you want custom visuals.

Step 1: Install and Import Pygame

Ensure Pygame is installed using pip (pip install pygame\) and then import it:

<span>import</span> <span>pygame</span>
<span>import</span> <span>sys</span>
<span>from</span> <span>pygame.locals</span> <span>import</span> <span>*</span>
<span>import</span> <span>time</span>
<span>import</span> <span>pygame</span>
<span>import</span> <span>sys</span>
<span>from</span> <span>pygame.locals</span> <span>import</span> <span>*</span>
<span>import</span> <span>time</span>
import pygame import sys from pygame.locals import * import time

Enter fullscreen mode Exit fullscreen mode

Step 2: Initialize Pygame

Set up the main display and clock:

<span>pygame</span><span>.</span><span>init</span><span>()</span>
<span>fps_clock</span> <span>=</span> <span>pygame</span><span>.</span><span>time</span><span>.</span><span>Clock</span><span>()</span>
<span>width</span><span>,</span> <span>height</span> <span>=</span> <span>400</span><span>,</span> <span>200</span>
<span>screen</span> <span>=</span> <span>pygame</span><span>.</span><span>display</span><span>.</span><span>set_mode</span><span>((</span><span>width</span><span>,</span> <span>height</span><span>))</span>
<span>pygame</span><span>.</span><span>display</span><span>.</span><span>set_caption</span><span>(</span><span>'</span><span>Time Tracker</span><span>'</span><span>)</span>
<span>pygame</span><span>.</span><span>init</span><span>()</span>
<span>fps_clock</span> <span>=</span> <span>pygame</span><span>.</span><span>time</span><span>.</span><span>Clock</span><span>()</span>

<span>width</span><span>,</span> <span>height</span> <span>=</span> <span>400</span><span>,</span> <span>200</span>
<span>screen</span> <span>=</span> <span>pygame</span><span>.</span><span>display</span><span>.</span><span>set_mode</span><span>((</span><span>width</span><span>,</span> <span>height</span><span>))</span>
<span>pygame</span><span>.</span><span>display</span><span>.</span><span>set_caption</span><span>(</span><span>'</span><span>Time Tracker</span><span>'</span><span>)</span>
pygame.init() fps_clock = pygame.time.Clock() width, height = 400, 200 screen = pygame.display.set_mode((width, height)) pygame.display.set_caption('Time Tracker')

Enter fullscreen mode Exit fullscreen mode

Step 3: Setup Display and Fonts

Define your display parameters and fonts:

<span>black</span> <span>=</span> <span>(</span><span>0</span><span>,</span> <span>0</span><span>,</span> <span>0</span><span>)</span>
<span>white</span> <span>=</span> <span>(</span><span>255</span><span>,</span> <span>255</span><span>,</span> <span>255</span><span>)</span>
<span>font</span> <span>=</span> <span>pygame</span><span>.</span><span>font</span><span>.</span><span>Font</span><span>(</span><span>None</span><span>,</span> <span>36</span><span>)</span>
<span>black</span> <span>=</span> <span>(</span><span>0</span><span>,</span> <span>0</span><span>,</span> <span>0</span><span>)</span>
<span>white</span> <span>=</span> <span>(</span><span>255</span><span>,</span> <span>255</span><span>,</span> <span>255</span><span>)</span>
<span>font</span> <span>=</span> <span>pygame</span><span>.</span><span>font</span><span>.</span><span>Font</span><span>(</span><span>None</span><span>,</span> <span>36</span><span>)</span>
black = (0, 0, 0) white = (255, 255, 255) font = pygame.font.Font(None, 36)

Enter fullscreen mode Exit fullscreen mode

Step 4: Timer Logic

Initialize timer variables and define the timer functions similar to Tkinter:

<span>start_time</span> <span>=</span> <span>None</span>
<span>elapsed_time</span> <span>=</span> <span>0</span>
<span>running</span> <span>=</span> <span>False</span>
<span>def</span> <span>start_timer</span><span>():</span>
<span>global</span> <span>running</span><span>,</span> <span>start_time</span>
<span>if</span> <span>not</span> <span>running</span><span>:</span>
<span>running</span> <span>=</span> <span>True</span>
<span>start_time</span> <span>=</span> <span>time</span><span>.</span><span>time</span><span>()</span> <span>-</span> <span>elapsed_time</span>
<span>def</span> <span>stop_timer</span><span>():</span>
<span>global</span> <span>running</span><span>,</span> <span>elapsed_time</span>
<span>if</span> <span>running</span><span>:</span>
<span>running</span> <span>=</span> <span>False</span>
<span>elapsed_time</span> <span>=</span> <span>time</span><span>.</span><span>time</span><span>()</span> <span>-</span> <span>start_time</span>
<span>start_time</span> <span>=</span> <span>None</span>
<span>elapsed_time</span> <span>=</span> <span>0</span>
<span>running</span> <span>=</span> <span>False</span>

<span>def</span> <span>start_timer</span><span>():</span>
    <span>global</span> <span>running</span><span>,</span> <span>start_time</span>
    <span>if</span> <span>not</span> <span>running</span><span>:</span>
        <span>running</span> <span>=</span> <span>True</span>
        <span>start_time</span> <span>=</span> <span>time</span><span>.</span><span>time</span><span>()</span> <span>-</span> <span>elapsed_time</span>

<span>def</span> <span>stop_timer</span><span>():</span>
    <span>global</span> <span>running</span><span>,</span> <span>elapsed_time</span>
    <span>if</span> <span>running</span><span>:</span>
        <span>running</span> <span>=</span> <span>False</span>
        <span>elapsed_time</span> <span>=</span> <span>time</span><span>.</span><span>time</span><span>()</span> <span>-</span> <span>start_time</span>
start_time = None elapsed_time = 0 running = False def start_timer(): global running, start_time if not running: running = True start_time = time.time() - elapsed_time def stop_timer(): global running, elapsed_time if running: running = False elapsed_time = time.time() - start_time

Enter fullscreen mode Exit fullscreen mode

Step 5: Main Event Loop

Create the loop to handle events and update the display:

<span>while</span> <span>True</span><span>:</span>
<span>screen</span><span>.</span><span>fill</span><span>(</span><span>black</span><span>)</span>
<span>for</span> <span>event</span> <span>in</span> <span>pygame</span><span>.</span><span>event</span><span>.</span><span>get</span><span>():</span>
<span>if</span> <span>event</span><span>.</span><span>type</span> <span>==</span> <span>QUIT</span><span>:</span>
<span>pygame</span><span>.</span><span>quit</span><span>()</span>
<span>sys</span><span>.</span><span>exit</span><span>()</span>
<span>elif</span> <span>event</span><span>.</span><span>type</span> <span>==</span> <span>KEYDOWN</span><span>:</span>
<span>if</span> <span>event</span><span>.</span><span>key</span> <span>==</span> <span>K_s</span><span>:</span>
<span>start_timer</span><span>()</span>
<span>elif</span> <span>event</span><span>.</span><span>key</span> <span>==</span> <span>K_p</span><span>:</span>
<span>stop_timer</span><span>()</span>
<span>if</span> <span>running</span><span>:</span>
<span>current_time</span> <span>=</span> <span>time</span><span>.</span><span>time</span><span>()</span>
<span>elapsed_time</span> <span>=</span> <span>current_time</span> <span>-</span> <span>start_time</span>
<span>mins</span><span>,</span> <span>secs</span> <span>=</span> <span>divmod</span><span>(</span><span>elapsed_time</span><span>,</span> <span>60</span><span>)</span>
<span>hrs</span><span>,</span> <span>mins</span> <span>=</span> <span>divmod</span><span>(</span><span>mins</span><span>,</span> <span>60</span><span>)</span>
<span>time_string</span> <span>=</span> <span>"</span><span>%d:%02d:%02d</span><span>"</span> <span>%</span> <span>(</span><span>hrs</span><span>,</span> <span>mins</span><span>,</span> <span>secs</span><span>)</span>
<span>else</span><span>:</span>
<span>mins</span><span>,</span> <span>secs</span> <span>=</span> <span>divmod</span><span>(</span><span>elapsed_time</span><span>,</span> <span>60</span><span>)</span>
<span>hrs</span><span>,</span> <span>mins</span> <span>=</span> <span>divmod</span><span>(</span><span>mins</span><span>,</span> <span>60</span><span>)</span>
<span>time_string</span> <span>=</span> <span>"</span><span>%d:%02d:%02d</span><span>"</span> <span>%</span> <span>(</span><span>hrs</span><span>,</span> <span>mins</span><span>,</span> <span>secs</span><span>)</span>
<span>time_text</span> <span>=</span> <span>font</span><span>.</span><span>render</span><span>(</span><span>time_string</span><span>,</span> <span>True</span><span>,</span> <span>white</span><span>)</span>
<span>time_rect</span> <span>=</span> <span>time_text</span><span>.</span><span>get_rect</span><span>()</span>
<span>time_rect</span><span>.</span><span>center</span> <span>=</span> <span>(</span><span>width</span> <span>//</span> <span>2</span><span>,</span> <span>height</span> <span>//</span> <span>2</span><span>)</span>
<span>screen</span><span>.</span><span>blit</span><span>(</span><span>time_text</span><span>,</span> <span>time_rect</span><span>)</span>
<span>pygame</span><span>.</span><span>display</span><span>.</span><span>update</span><span>()</span>
<span>fps_clock</span><span>.</span><span>tick</span><span>(</span><span>fps</span><span>)</span>
<span>while</span> <span>True</span><span>:</span>
    <span>screen</span><span>.</span><span>fill</span><span>(</span><span>black</span><span>)</span>
    <span>for</span> <span>event</span> <span>in</span> <span>pygame</span><span>.</span><span>event</span><span>.</span><span>get</span><span>():</span>
        <span>if</span> <span>event</span><span>.</span><span>type</span> <span>==</span> <span>QUIT</span><span>:</span>
            <span>pygame</span><span>.</span><span>quit</span><span>()</span>
            <span>sys</span><span>.</span><span>exit</span><span>()</span>
        <span>elif</span> <span>event</span><span>.</span><span>type</span> <span>==</span> <span>KEYDOWN</span><span>:</span>
            <span>if</span> <span>event</span><span>.</span><span>key</span> <span>==</span> <span>K_s</span><span>:</span>
                <span>start_timer</span><span>()</span>
            <span>elif</span> <span>event</span><span>.</span><span>key</span> <span>==</span> <span>K_p</span><span>:</span>
                <span>stop_timer</span><span>()</span>

    <span>if</span> <span>running</span><span>:</span>
        <span>current_time</span> <span>=</span> <span>time</span><span>.</span><span>time</span><span>()</span>
        <span>elapsed_time</span> <span>=</span> <span>current_time</span> <span>-</span> <span>start_time</span>
        <span>mins</span><span>,</span> <span>secs</span> <span>=</span> <span>divmod</span><span>(</span><span>elapsed_time</span><span>,</span> <span>60</span><span>)</span>
        <span>hrs</span><span>,</span> <span>mins</span> <span>=</span> <span>divmod</span><span>(</span><span>mins</span><span>,</span> <span>60</span><span>)</span>
        <span>time_string</span> <span>=</span> <span>"</span><span>%d:%02d:%02d</span><span>"</span> <span>%</span> <span>(</span><span>hrs</span><span>,</span> <span>mins</span><span>,</span> <span>secs</span><span>)</span>
    <span>else</span><span>:</span>
        <span>mins</span><span>,</span> <span>secs</span> <span>=</span> <span>divmod</span><span>(</span><span>elapsed_time</span><span>,</span> <span>60</span><span>)</span>
        <span>hrs</span><span>,</span> <span>mins</span> <span>=</span> <span>divmod</span><span>(</span><span>mins</span><span>,</span> <span>60</span><span>)</span>
        <span>time_string</span> <span>=</span> <span>"</span><span>%d:%02d:%02d</span><span>"</span> <span>%</span> <span>(</span><span>hrs</span><span>,</span> <span>mins</span><span>,</span> <span>secs</span><span>)</span>

    <span>time_text</span> <span>=</span> <span>font</span><span>.</span><span>render</span><span>(</span><span>time_string</span><span>,</span> <span>True</span><span>,</span> <span>white</span><span>)</span>
    <span>time_rect</span> <span>=</span> <span>time_text</span><span>.</span><span>get_rect</span><span>()</span>
    <span>time_rect</span><span>.</span><span>center</span> <span>=</span> <span>(</span><span>width</span> <span>//</span> <span>2</span><span>,</span> <span>height</span> <span>//</span> <span>2</span><span>)</span>
    <span>screen</span><span>.</span><span>blit</span><span>(</span><span>time_text</span><span>,</span> <span>time_rect</span><span>)</span>

    <span>pygame</span><span>.</span><span>display</span><span>.</span><span>update</span><span>()</span>
    <span>fps_clock</span><span>.</span><span>tick</span><span>(</span><span>fps</span><span>)</span>
while True: screen.fill(black) for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() elif event.type == KEYDOWN: if event.key == K_s: start_timer() elif event.key == K_p: stop_timer() if running: current_time = time.time() elapsed_time = current_time - start_time mins, secs = divmod(elapsed_time, 60) hrs, mins = divmod(mins, 60) time_string = "%d:%02d:%02d" % (hrs, mins, secs) else: mins, secs = divmod(elapsed_time, 60) hrs, mins = divmod(mins, 60) time_string = "%d:%02d:%02d" % (hrs, mins, secs) time_text = font.render(time_string, True, white) time_rect = time_text.get_rect() time_rect.center = (width // 2, height // 2) screen.blit(time_text, time_rect) pygame.display.update() fps_clock.tick(fps)

Enter fullscreen mode Exit fullscreen mode

Conclusion

In summary, both Tkinter and Pygame provide robust frameworks for developing a time tracking application with graphical user interfaces in Python. While Tkinter is more straightforward and suitable for typical application interfaces, Pygame offers enhanced control over graphic elements and animations, which can be particularly beneficial for applications requiring dynamic visual displays. The selection between these two should be based on the specific requirements and objectives of the project, as well as the developer’s familiarity with the libraries.

Read this article and more on fzeba.com.

原文链接:Build a Time Tracking App with Tkinter and Pygame

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
It is by acts and not by ideas that people live.
行动是根本,想法锦上添花
评论 抢沙发

请登录后发表评论

    暂无评论内容