Python 销毁Tkinter标签并关闭VLC

Python 销毁Tkinter标签并关闭VLC,python,tkinter,Python,Tkinter,我目前正在尝试开发一个Pomodoro应用程序,该程序将包括几个屏幕(Tkinter框架),例如一个指示下一个任务的StartWorking屏幕和一个“Go”按钮,该按钮将在启动VLC的同时显示一个倒计时屏幕 在倒计时结束时,会出现SprintEnd屏幕,确认执行的任务是计划的任务 当前代码如下: import logging #To log activity import tkinter as tk #To manage GUI from tkinter import ttk #For mor

我目前正在尝试开发一个Pomodoro应用程序,该程序将包括几个屏幕(Tkinter框架),例如一个指示下一个任务的StartWorking屏幕和一个“Go”按钮,该按钮将在启动VLC的同时显示一个倒计时屏幕

在倒计时结束时,会出现SprintEnd屏幕,确认执行的任务是计划的任务

当前代码如下:

import logging #To log activity
import tkinter as tk #To manage GUI
from tkinter import ttk #For more modern displays in the GUI
from datetime import datetime, timedelta #To manage dates and times
import time #To manage sleep time
from PIL import Image as PIL_Image, ImageTk as PIL_ImageTk #To manage image conversions
import pandas as pd #To read from and write in the csv database
import os #To manage paths
import random #To choose random music from the playlist
import subprocess #To launch VLC

# Default style
TITLE_FONT = ('Verdana', 18)
SUBTITLE_FONT = ('Verdana', 7, 'italic')
LARGE_FONT = ('Verdana', 12, 'bold')
SMALL_FONT = ('Verdana', 8)

class Window(tk.Tk):
        def __init__(self, *args, **kwargs):
            """ Creation of the main window that will host each frame"""

            tk.Tk.__init__(self, *args, **kwargs)
            tk.Tk.iconbitmap(self, default='img/tomato.ico')
            tk.Tk.title(self, 'My Pomodoro app')
            #tk.Tk.minsize(self, 400, 400)

            # Creating a main container that will display the current frame 
            container = tk.Frame(self)
            container.grid(sticky='nsew')
            container.grid_rowconfigure(0, weight=1)
            container.grid_columnconfigure(0, weight=1)

            # Listing all the frames that can be displayed in our container
            self.frames = {}
            for frm in (Welcome, StartWorking, Countdown, SprintEnd, Planning, Planning_tasks, Monitoring):
                frame = frm(container, self)
                self.frames[frm] = frame
                frame.grid(row=0, column=0, sticky='nsew')
            self.show_frame(Welcome)


        def show_frame(self, container):
            """Function that will bring up the current frame in our container

            Args:
                container (tkinter Frame): an empty frame that will display another selected frame in itself above all others
            """
            frame = self.frames[container]
            frame.tkraise()


        def start_countdown(self, duration):
            # Starting soft music from the playlist within VLC
            playlist = os.listdir('audio/playlist')
            music = random.randint(0, len(playlist) - 1)
            subprocess.Popen(['C:/Program Files/VideoLAN/VLC/vlc.exe', ''.join(['audio/playlist/', playlist[music]])])
            
            # Countdown passed into seconds
            duration = duration * 60
            while duration > 0:
                mins, secs = divmod(duration, 60)
                timeleft_label = tk.Label(self, text='{:02d}:{:02d}'.format(mins, secs), font=LARGE_FONT)
                timeleft_label.grid(row=1, column=0, pady=20, padx=10, sticky='nsew')
                
                self.update()
                self.wm_attributes('-topmost', 1)
                time.sleep(1)
                duration -= 1

            # End of countdown
            timeleft_label.destroy()
            subprocess.call(['C:/Program Files/VideoLAN/VLC/vlc.exe', 'vlc://quit'], shell=False)

            self.show_frame(SprintEnd)
            return  


class Welcome(tk.Frame):

    def __init__(self, parent, controller):
        """ Welcome page that will enable to choose between 3 options: planning, working or monitoring.

        Args:
            parent (tkinter Frame): a widget (Window) to act as the parent of the current object
            controller (tkinter Frame): object that is designed to act as a common point of interaction for several pages of widgets
        """
        # Main title
        tk.Frame.__init__(self,parent)
        title = tk.Label(self, text='Welcome to My Pomodoro', font=TITLE_FONT)
        title.grid(pady=20,padx=10, sticky='nsew', row=0, column=0, columnspan=3)

        # Subtitle
        subtitle = tk.Label(self, text='powered by Blue Owl', font=SUBTITLE_FONT)
        subtitle.grid(padx=10, pady=5, sticky='e', row=1, column=2)

        # Main image
        image = PIL_Image.open(r'img/tomato.png')
        photo = PIL_ImageTk.PhotoImage(image)
        logo = tk.Label(self, image=photo)
        logo.image = photo
        logo.grid(row=2, column=0, columnspan=3, sticky='nsew', pady=20)

        # Navigation buttons to reach other pages
        """These buttons actually raise other frames on top of the current one within the same container"""
        button_navigate_working = ttk.Button(self, text='Start working', command=lambda: controller.show_frame(StartWorking))
        button_navigate_working.grid(row=3, column=0, padx=10, pady=30, sticky='sew')

        button_navigate_planning = ttk.Button(self, text='Planning', command=lambda: controller.show_frame(Planning))
        button_navigate_planning.grid(row=3, column=1, padx=10, pady=30, sticky='sew')

        button_navigate_monitoring = ttk.Button(self, text='Monitoring', command=lambda: controller.show_frame(Monitoring))
        button_navigate_monitoring.grid(row=3, column=2, padx=10, pady=30, sticky='sew')



class StartWorking(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        title = tk.Label(self, text='Start Working', font=TITLE_FONT)
        title.grid(pady=20,padx=10, sticky='nsew', row=0, column=0, columnspan=4)

        # Reading from database
        dataframe = pd.read_csv('files/db_test.csv', sep=';')
        
        # Converting strings objects into datetime objects
        dataframe['Datetime'] = pd.to_datetime(dataframe['Day'] + ' ' + dataframe['Time'], format='%d/%m/%Y %H:%M')
        dataframe['Deltatime'] = datetime.now() - dataframe['Datetime']

        # Comparing to current datetime and identifying next planned task
        future_filter = (dataframe['Deltatime'] < timedelta(0))
        dataframe_future = dataframe.loc[(future_filter)]
        try:
            next_task = dataframe_future.loc[dataframe_future['Deltatime'].idxmax()]['Planned task']

            # Display next task and start working
            label_next_task = tk.Label(self, text='Next task :', font=SMALL_FONT)
            label_next_task.grid(pady=50,padx=10, sticky='nsew', row=1, column=1)

            label_task = tk.Label(self, text=next_task, font=LARGE_FONT)
            label_task.grid(pady=50,padx=10, sticky='nsew', row=1, column=2)

            button_navigate_countdown = ttk.Button(self, text='Start task !', command=lambda: [controller.show_frame(Countdown), controller.start_countdown(25)])
            button_navigate_countdown.grid(row=2, column=1, columnspan=2, padx=10, pady=30)
        except ValueError:
            # If there is no future task planned yet, user has to plan first
            next_task = 'Not planned yet'
            
            label_task = tk.Label(self, text='No task planned !', font=LARGE_FONT, fg='red')
            label_task.grid(pady=20,padx=10, sticky='nsew', row=1, column=1, columnspan=2)
            
            button_navigate_countdown = ttk.Button(self, text='Back to planning', command=lambda: controller.show_frame(Planning))
            button_navigate_countdown.grid(row=2, column=1, columnspan=2, padx=10, pady=10)

        # Navigation buttons to reach other pages
        """They actually raise other frames on top of the current one within the same container"""
        button_navigate_working = ttk.Button(self, text='Back to home', command=lambda: controller.show_frame(Welcome))
        button_navigate_working.grid(row=3, column=0, padx=10, pady=30, sticky='sew')

        button_navigate_planning = ttk.Button(self, text='Planning', command=lambda: controller.show_frame(Planning))
        button_navigate_planning.grid(row=3, column=1, padx=10, pady=30, sticky='sew')

        button_navigate_monitoring = ttk.Button(self, text='Monitoring', command=lambda: controller.show_frame(Monitoring))
        button_navigate_monitoring.grid(row=3, column=2, padx=10, pady=30, sticky='sew')

        button_navigate_monitoring = ttk.Button(self, text='End of sprint', command=lambda: controller.show_frame(SprintEnd))
        button_navigate_monitoring.grid(row=3, column=3, padx=10, pady=30, sticky='sew')

        

class SprintEnd(tk.Frame):
    def __init__(self, parent, controller):
        """ Work page that will enable to validate the latest task and rate it, then to launch a new task.

        Args:
            parent (tkinter Frame): a widget (Window) to act as the parent of the current object
            controller (tkinter Frame): object that is designed to act as a common point of interaction for several pages of widgets
        """
        tk.Frame.__init__(self, parent)
        # Main title
        title = tk.Label(self, text='End of sprint', font=TITLE_FONT)
        title.grid(pady=20,padx=10, sticky='nsew', row=0, column=0, columnspan=3)

        # Loading images
        validate_icon = tk.PhotoImage(file=r'img/validate.png').subsample(10, 10)

        # Reading from database
        dataframe = pd.read_csv('files/db_test.csv', sep=';')
        
        # Converting strings objects into datetime objects
        dataframe['Datetime'] = pd.to_datetime(dataframe['Day'] + ' ' + dataframe['Time'], format='%d/%m/%Y %H:%M')

        # Comparing to current datetime and identifying most recent planned task
        dataframe['Deltatime'] = datetime.now() - dataframe['Datetime']
        past_filter = (dataframe['Deltatime'] >= timedelta(0))
        dataframe_past = dataframe.loc[(past_filter)]
        try:
            latest_task = dataframe_past.loc[dataframe_past['Deltatime'].idxmin()]['Planned task']
            latest_index = dataframe_past.loc[dataframe_past['Deltatime'].idxmin()]
        except ValueError:
            latest_task = 'Undefined'
            latest_index = {
                'Day' : datetime.now().strftime('%d/%m/%Y'),
                'Time' : datetime.now().strftime('%H:%M'),
                'Planned task' : 'Undefined',
                'Personnal' : 'Private',
                'Actual task' : 'Undefined',
                'Efficiency' : 1
            }

        # Comparing to current datetime and identifying next planned task
        future_filter = (dataframe['Deltatime'] < timedelta(0))
        dataframe_future = dataframe.loc[(future_filter)]
        try:
            next_task = dataframe_future.loc[dataframe_future['Deltatime'].idxmax()]['Planned task']
        except ValueError:
            next_task = 'Undefined'

        # Displaying latest planned task information in the frame
        latest_task_label1 = tk.Label(self, text='Latest planned task', font=SMALL_FONT)
        latest_task_label1.grid(pady=5, padx=10, sticky='nsew', row=1, column=1)

        latest_task_label2 = tk.Label(self, text=latest_task, font=LARGE_FONT)
        latest_task_label2.grid(pady=5, padx=10, sticky='nsew', row=2, column=1)

        # Displaying labels about actual latest task
        real_latest_task_label = tk.Label(self, text='Actual task', font=SMALL_FONT)
        real_latest_task_label.grid(pady=5, padx=10, sticky='nsew', row=3, column=0)
        privacy_latest_task_label = tk.Label(self, text='Private', font=SMALL_FONT)
        privacy_latest_task_label.grid(pady=5, padx=10, sticky='nsew', row=3, column=1)
        efficiency_latest_task_label = tk.Label(self, text='Efficiency', font=SMALL_FONT)
        efficiency_latest_task_label.grid(pady=5, padx=10, sticky='nsew', row=3, column=2)
        
        # Getting information about actual latest task
        real_task = tk.StringVar()
        real_latest_task = ttk.Entry(self, textvariable=real_task)
        real_latest_task.grid(pady=5, padx=10, sticky='nsew', row=4, column=0)
        privacy = tk.StringVar()
        privacy_latest_task = tk.Checkbutton(self, variable=privacy, onvalue='Private', offvalue='Professional', justify='center')
        privacy_latest_task.deselect()
        privacy_latest_task.grid(pady=5, padx=10, sticky='nsew', row=4, column=1)
        efficiency=tk.IntVar()
        efficiency_latest_task = ttk.Entry(self, textvariable=efficiency)
        efficiency_latest_task.grid(pady=5, padx=10, sticky='nsew', row=4, column=2)

        next_task_label1 = tk.Label(self, text='Next planned task', font=SMALL_FONT)
        next_task_label1.grid(pady=5, padx=10, sticky='nsew', row=5, column=1)

        next_task_label2 = tk.Label(self, text=next_task, font=LARGE_FONT)
        next_task_label2.grid(pady=5, padx=10, sticky='nsew', row=6, column=1)

        validate_button = ttk.Button(self, text='Validate all', image=validate_icon, compound='left',
                        command=lambda: self.validate_input(controller, real_task, privacy, efficiency, latest_index, dataframe))
        validate_button.grid(pady=20, padx=10, sticky='nsew', row=7, column=2)

        # Navigation buttons to reach other pages
        """They actually raise other frames on top of the current one within the same container"""
        button_navigate_working = ttk.Button(self, text='Back to home', command=lambda: controller.show_frame(Welcome))
        button_navigate_working.grid(row=9, column=0, pady=10, padx=10)

        button_navigate_planning = ttk.Button(self, text='Planning', command=lambda: controller.show_frame(Planning))
        button_navigate_planning.grid(row=9, column=1, pady=10, padx=10)

        button_navigate_monitoring = ttk.Button(self, text='Monitoring', command=lambda: controller.show_frame(Monitoring))
        button_navigate_monitoring.grid(row=9, column=2, pady=10, padx=10)
    
    def validate_input(self, controller, real_task, privacy, efficiency, latest_index, dataframe):
        """ Function that will be triggered when clicking on validation button

        Args:
            real_task (StringVar): task that has actually be completed during the previous sprint
            privacy (StringVar): indicates whether the completed task was private or professional
            efficiency (IntVar): rates the efficiency of the latest sprint from 1 (inefficient) to 4 (very efficient)
            latest_index (Pandas.Series): full record corresponding to the latest task
            dataframe (Pandas.DataFrame) : full database
        """
        latest_index['Personal'] = privacy.get()

        # Ensuring that latest task is not empty
        if real_task.get() == '':
            error_label = tk.Message(self, text='Please input your latest task',
                        font=SMALL_FONT, foreground='red', width=100, justify='center')
        else:
            latest_index['Actual task'] = real_task.get()
            
            # Ensuring that efficiency is a number between 1 and 4
            try:
                if 1 <= efficiency.get() <= 4:
                    latest_index['Efficiency'] = efficiency.get()
                else:
                    error_label = tk.Message(self, text='Please enter a value between 1 (inefficient) and 4 (very efficient) for efficiency',
                                font=SMALL_FONT, foreground='red', width=100, justify='center')
            except:
                error_label = tk.Message(self, text='Please input a value between 1 and 4 for efficiency',
                                font=SMALL_FONT, foreground='red', width=100, justify='center')
        try:
            error_label.grid(pady=2, padx=10, sticky='nsew', row=8, column=2)
        
        # If error_label does not exist, the input is valid
        except UnboundLocalError:
            # The error message is converted into a success message
            error_label = tk.Message(self, text='Succesfully updated', font=SMALL_FONT, foreground='green', width=100, justify='center')
            error_label.grid(pady=2, padx=10, sticky='nsew', row=8, column=2)
            
            # Dataframe is updated with the latest record
            dataframe.set_index('Datetime', inplace=True)
            latest_record = latest_index.to_frame().transpose()
            latest_record.set_index('Datetime', inplace=True)
            dataframe.update(latest_record)
            header = ['Day', 'Time', 'Planned task', 'Personal', 'Actual task', 'Efficiency']
            try:
                dataframe[header].sort_index(ascending=True).to_csv('files/db_test.csv', index=False, sep=';')
            except PermissionError:
                error_label = tk.Message(self, text='File already open !', font=SMALL_FONT, foreground='red', width=100, justify='center')
                error_label.grid(pady=2, padx=10, sticky='nsew', row=8, column=2)

            # The message is displayed for 1 second, then we move to the next task
            time.sleep(1) # Message not displayed
            controller.show_frame(StartWorking)



class Planning(tk.Frame):
    def __init__(self, parent, controller):
        """
        Work page that will enable to plan tasks for a defined day.

        Args:
            parent (tkinter Frame): a widget (Window) to act as the parent of the current object
            controller (tkinter Frame): object that is designed to act as a common point of interaction for several pages of widgets
        """
        tk.Frame.__init__(self, parent)
        # Main title
        title = tk.Label(self, text='Planning', font=TITLE_FONT)
        title.grid(pady=30,padx=10, sticky='nsew', row=0, column=0, columnspan=3)
        
        # Input date of the day planned
        date_label = tk.Label(self, text='Day planned (format DD/MM/YYYY)', font=LARGE_FONT, justify='center')
        date_label.grid(pady=10,padx=10, sticky='nsew', row=1, column=0, columnspan=3)

        date = tk.StringVar()
        date_entry = ttk.Entry(self, textvariable=date)
        date_entry.grid(pady=10,padx=10, sticky='nsew', row=2, column=1)

        validate_icon = tk.PhotoImage(file=r'img/validate.png').subsample(10, 10)
        validate_button = ttk.Button(self, text='Validate', image=validate_icon, compound='left',
                        command=lambda: self.validate_date(controller, date))
        validate_button.grid(pady=30, padx=10, sticky='nsew', row=3, column=1)

        # Navigation buttons to reach other pages
        """They actually raise other frames on top of the current one within the same container"""
        button_navigate_working = ttk.Button(self, text='Back to home', command=lambda: controller.show_frame(Welcome))
        button_navigate_working.grid(row=9, column=0, pady=10, padx=10)

        button_navigate_planning = ttk.Button(self, text='Start Working', command=lambda: controller.show_frame(StartWorking))
        button_navigate_planning.grid(row=9, column=1, pady=10, padx=10)

        button_navigate_monitoring = ttk.Button(self, text='Monitoring', command=lambda: controller.show_frame(Monitoring))
        button_navigate_monitoring.grid(row=9, column=2, pady=10, padx=10)

    def validate_date(self, controller, date):
        """Checks the validity of the input day.

        Args:
            date (StringVar): date of the day that is to be planned
        """
        if date.get() == '':
            error_label = tk.Message(self, text='Please input your latest task',
                        font=SMALL_FONT, foreground='red', width=140, justify='center')
        else:
            input_date = str(date.get())

            try:
                date_array = input_date.split('/')
                day = int(date_array[0])
                month = int(date_array[1])
                year = int(date_array[2])
                if day < 1 or  31 < day or month < 1 or 12 < month or year < 2020 or 2100 < year:
                    error_label = tk.Message(self, text='Please input a valid date',
                                        font=SMALL_FONT, foreground='red', width=140, justify='center')

            except (TypeError, ValueError, IndexError):
                error_label = tk.Message(self, text='Please input a valid date (format DD/MM/YYYY)',
                                    font=SMALL_FONT, foreground='red', width=140, justify='center')
        try:
            error_label.grid(pady=10, padx=10, sticky='nsew', row=4, column=1)
        # If error_label does not exist, the input is valid
        except UnboundLocalError:
            # Swap to Planning window
            controller.show_frame(Planning_tasks)
        return str(date.get())



class Planning_tasks(ttk.Frame):
    def __init__(self, parent, controller):
        tk.ttk.Frame.__init__(self, parent)
        # Main title
        title = ttk.Label(self, text='Planning', font=TITLE_FONT)
        title.grid(pady=20,padx=10, sticky='nsew', row=0, column=0, columnspan=3)

        # Default sprints
        sprints = pd.DataFrame({'Time': ['7:30', '8:00', '8:30', '9:00', '10:00', '10:30', '11:00', '13:00', '13:30', '14:00', '15:00', '15:30', '16:00', '16:30'],
                                'Planned_task_list': ['', '', '', '', '', '', '', '', '', '', '', '', '', '']})
        sprints.set_index('Time', inplace=True)

        for row in sprints:
            pass
            #print(row)
            #label_start_time = tk.Label(self, text=row['Time'], font=LARGE_FONT, justify='center')
            #label_start_time.grid(row=index+1, column=0, pady=10, padx=10)

        #Déclencher au clic sur delete ou ajout
        #lambda: self.display_sprints(sprints)

        # Navigation buttons to reach other pages
        """They actually raise other frames on top of the current one within the same container"""
        button_navigate_working = ttk.Button(self, text='Back to home', command=lambda: controller.show_frame(Welcome))
        button_navigate_working.grid(row=50, column=0, pady=10, padx=10)

        button_navigate_planning = ttk.Button(self, text='Start Working', command=lambda: controller.show_frame(StartWorking))
        button_navigate_planning.grid(row=50, column=1, pady=10, padx=10)

        button_navigate_monitoring = ttk.Button(self, text='Monitoring', command=lambda: controller.show_frame(Monitoring))
        button_navigate_monitoring.grid(row=50, column=2, pady=10, padx=10)

    def display_sprints(self, sprints):
        """Displays the correct amount of sprints for the day

        Args:
            sprints (pandas.DataFrame): contains time (indexes) and planned task for each sprint
        """
        for index, row in sprints:
            label_start_time = tk.Label(self, text=row['Time'], font=LARGE_FONT, justify='center')
            label_start_time.grid(row=index+1, column=0, pady=10, padx=10)



class Countdown(ttk.Frame):
    def __init__(self, parent, controller):
        tk.ttk.Frame.__init__(self, parent)

        # Reading from database
        dataframe = pd.read_csv('files/db_test.csv', sep=';')
        
        # Converting strings objects into datetime objects
        dataframe['Datetime'] = pd.to_datetime(dataframe['Day'] + ' ' + dataframe['Time'], format='%d/%m/%Y %H:%M')
        dataframe['Deltatime'] = datetime.now() - dataframe['Datetime']

        # Comparing to current datetime and identifying next planned task
        future_filter = (dataframe['Deltatime'] < timedelta(0))
        dataframe_future = dataframe.loc[(future_filter)]
        
        # No need for a control on the existence of the value, as it has just been done in StartWorking frame
        next_task = dataframe_future.loc[dataframe_future['Deltatime'].idxmax()]['Planned task']

        # Display next task
        label_task = tk.Label(self, text=next_task, font=LARGE_FONT)
        label_task.grid(pady=80,padx=10, sticky='nsew', row=0, column=0)

        # Go back to previous screen in case of interruption
        button_interrupt = ttk.Button(self, text='Interrupt', command=lambda: controller.show_frame(StartWorking))
        button_interrupt.grid(row=2, column=0, pady=10, padx=10, sticky='sew')
        


class Monitoring(ttk.Frame):
    def __init__(self, parent, controller):
        tk.ttk.Frame.__init__(self, parent)
        title = ttk.Label(self, text='Monitoring', font=TITLE_FONT)
        title.grid(pady=20,padx=10, sticky='nsew', row=0, column=0, columnspan=3)

        # Navigation buttons to reach other pages
        """They actually raise other frames on top of the current one within the same container"""
        button_navigate_working = ttk.Button(self, text='Back to home', command=lambda: controller.show_frame(Welcome))
        button_navigate_working.grid(row=9, column=0, pady=10, padx=10)

        button_navigate_planning = ttk.Button(self, text='Start Working', command=lambda: controller.show_frame(StartWorking))
        button_navigate_planning.grid(row=9, column=1, pady=10, padx=10)

        button_navigate_monitoring = ttk.Button(self, text='Planning', command=lambda: controller.show_frame(Planning))
        button_navigate_monitoring.grid(row=9, column=2, pady=10, padx=10)


app = Window()
app.mainloop()
导入日志记录#记录活动
将tkinter作为tk导入以管理GUI
从tkinter导入ttk#以在GUI中实现更现代化的显示
从datetime导入datetime、timedelta#管理日期和时间
导入时间#管理睡眠时间
从PIL import Image as PIL_Image、ImageTk as PIL_ImageTk#管理图像转换
导入熊猫作为pd#从csv数据库中读取和写入
导入操作系统以管理路径
导入随机#从播放列表中选择随机音乐
导入子流程#以启动VLC
#默认样式
标题字体=('Verdana',18)
副标题字体=('Verdana',7,'italic')
大字体=('Verdana',12,'bold')
小字体=('Verdana',8)
类窗口(tk.tk):
定义初始化(self,*args,**kwargs):
“”“创建将承载每个帧的主窗口”“”
tk.tk.\uuuuu初始化(self,*args,**kwargs)
tk.tk.iconbitmap(self,default='img/tomato.ico')
tk.tk.title(self,“我的Pomodoro应用程序”)
#tk.tk.minsize(self,400400)
#创建将显示当前帧的主容器
容器=tk.框架(自身)
container.grid(sticky='nsew')
container.grid_rowconfigure(0,权重=1)
container.grid\u column配置(0,权重=1)
#列出可以在容器中显示的所有帧
self.frames={}
对于frm in(欢迎、开始工作、倒计时、冲刺结束、计划、计划任务、监控):
帧=frm(容器,自身)
自帧[frm]=帧
frame.grid(行=0,列=0,sticky='nsew')
自我展示框架(欢迎)
def显示_框架(自身、容器):
“”函数,该函数将在容器中显示当前帧
Args:
容器(tkinter帧):一个空帧,它将在所有其他帧之上显示另一个选定帧
"""
frame=self.frames[container]
frame.tkraise()
def start_倒计时(自身、持续时间):
#从VLC内的播放列表启动软音乐
playlist=os.listdir('音频/播放列表')
music=random.randint(0,len(播放列表)-1)
subprocess.Popen(['C:/Program Files/VideoLAN/VLC/VLC.exe','.join(['audio/playlist/',playlist[music]]))
#倒数以秒为单位
持续时间=持续时间*60
当持续时间>0时:
分钟,秒=divmod(持续时间,60)
timeleft_label=tk.label(self,text='{:02d}:{:02d}'。格式(分,秒),字体=大字体)
timeleft_label.grid(行=1,列=0,pady=20,padx=10,sticky='nsew')
self.update()
self.wm_属性('-top',1)
时间。睡眠(1)
持续时间-=1
#倒计时结束
timeleft_label.destroy()
子进程调用(['C:/ProgramFiles/VideoLAN/VLC/VLC.exe','vlc://quit'],shell=False)
self.show_框架(SprintEnd)
返回
班级欢迎(tk.Frame):
定义初始化(自、父、控制器):
“”“欢迎页面,允许在3个选项中进行选择:计划、工作或监视。”。
Args:
父对象(tkinter帧):用作当前对象父对象的小部件(窗口)
控制器(tkinter框架):设计用于充当多页小部件的公共交互点的对象
"""
#主标题
tk.Frame.\uuuu init\uuuuu(自,父)
title=tk.Label(self,text='Welcome to My Pomotoro',font=title\u font)
title.grid(pady=20,padx=10,sticky='nsew',行=0,列=0,列span=3)
#副标题
subtitle=tk.Label(self,text='powered by Blue Owl',font=subtitle\u font)
副标题.网格(padx=10,pady=5,sticky=e',行=1,列=2)
#主图像
image=PIL_image.open(r'img/tomato.png')
photo=PIL_ImageTk.PhotoImage(图像)
logo=tk.标签(自我,图像=照片)
logo.image=照片
logo.grid(行=2,列=0,列span=3,粘性=nsew',pady=20)
#用于访问其他页面的导航按钮
“”“这些按钮实际上会在同一容器中当前帧的顶部升起其他帧”“”
button\u navigate\u working=ttk.button(self,text='Start working',command=lambda:controller.show\u frame(StartWorking))
按钮导航工作网格(行=3,列=0,padx=10,pady=30,sticky='sew')
按钮\导航\计划=ttk.按钮(self,text='planning',command=lambda:controller.show\框架(计划))
按钮导航计划网格(行=3,列=1,padx=10,pady=30,sticky='sew')
按钮\导航\监控=ttk.按钮(self,text='monitoring',command=lambda:controller.show\帧(监控))
按钮导航监视网格(行=3,列=2,padx=10,pady=30,sticky='sew')
类StartWorking(tk.Frame):
定义初始化(自、父、控制器):
tk.Frame.\uuuu init\uuuuu(自,父)
title=tk.Label(self,text='Start Working',font=title\u font)
title.grid(pady=20,padx=10,sticky='nsew',行=0,列=0,列span=4)
#从数据库读取
dataframe=pd.read_csv('files/db_test.csv',sep=';')
#将字符串对象转换为日期时间对象
dataframe['Datetime']=pd.to_Datetime(dataframe['Day']+''+dataframe['Time'],格式='%d/%m/%Y%H:%m')
数据帧
os.system('TASKKILL /F /IM VLC.EXE')