用tkinter写一个应用计时程序

 程序主要是用来对游戏计时的,当然其他的应用程序也是可以的,不过应该会有些Bug存在,因为在监控进程的时候,只取了匹配到的第一个PID,也就意味着无法区分是父进程还是子进程,不过对于监控游戏而言,这个问题应该影响不大...

 

 

 

用到的模块:

import tkinter as tk
from tkinter import filedialog,Frame,messagebox
import psutil
import os
import win32api
from datetime import datetime
import time
from dateutil import parser

具体代码:

  1 class GUI(Frame):
  2 
  3     def __init__(self):
  4         super().__init__()
  5         self.exeFile = tk.Variable()
  6         self.saveFile = tk.Variable()
  7 
  8         self.start = None
  9         self.end = None
 10         self.sum = None
 11 
 12         self.pid = None
 13 
 14         self.time = tk.Variable()
 15         self.time.set("游戏运行时间:00:00:00")
 16 
 17         self.nowTime = tk.Variable()
 18         self.nowTime.set(self.get_nowtime())
 19         self.startTime = tk.Variable()
 20         self.startTime.set("游戏开始时间:0000-00-00 00:00:00")
 21         self.endTime = tk.Variable()
 22         self.endTime.set("游戏结束时间:0000-00-00 00:00:00")
 23 
 24         self.set_gui()
 25 
 26     def set_gui(self):
 27         #设置控件
 28         self.master.title("Running Time of The Game")
 29         self.master.geometry("464x362+500+200")
 30         self.pack()
 31 
 32         frm1= Frame(self,width=400,height=90).pack(pady=17)
 33         game_entry = tk.Entry(frm1, textvariable=self.exeFile, width=35).place(relx=0.19, rely=0.09)
 34         save_entry = tk.Entry(frm1, textvariable=self.saveFile, width=35).place(relx=0.19, rely=0.21)
 35         exe_button = tk.Button(frm1,text="载入程序",command=self.get_exe,width=7).place(relx=0.77,rely=0.077)
 36         save_button = tk.Button(frm1,text="选择文本",command=self.start_time,width=7).place(relx=0.77,rely=0.2)
 37 
 38         frm2 = Frame(self,width=400,height=180).pack()
 39         label1 = tk.Label(frm2, textvariable = self.nowTime, width=50).place(relx=0.08, rely=0.36)
 40         self.after(1000, self.reflash_nowtime)
 41         label2 = tk.Label(frm2, textvariable = self.startTime, width=50).place(relx=0.08, rely=0.47)
 42         label3 = tk.Label(frm2, textvariable=self.endTime, width=50).place(relx=0.08, rely=0.58)
 43         label4 = tk.Label(frm2, textvariable=self.time, width=50).place(relx=0.08, rely=0.69)
 44 
 45         frm3 = Frame(self,width=400,height=45).pack(pady=10)
 46         run_button = tk.Button(frm3,text="运行",command=self.run,width=7).place(relx=0.2,rely=0.85)
 47         exit_button = tk.Button(frm3,text="退出",command=self.quit,width=7).place(relx=0.8,rely=0.85)
 48         statistics_button = tk.Button(frm3,text="统计",command=self.statistics_time,width=7).place(relx=0.5,rely=0.85)
 49 
 50     def get_exe(self):
 51         #在game_entry中显示游戏的路径
 52         file = filedialog.askopenfilename()
 53         self.exeFile.set(file)
 54 
 55     def get_nowtime(self,flag=None):
 56         #获取当前系统时间,flag用于区分是否点击了"运行按钮"
 57         if flag is None:
 58             now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
 59             return "当前系统时间:" + now
 60         else:
 61             sum_time = "程序运行总时间:00:00:00"
 62             return sum_time
 63 
 64     def reflash_nowtime(self):
 65         #利用after()方法达到定时器的作用,即:实现窗体时间按秒递加
 66         self.nowTime.set(self.get_nowtime())
 67         self.after(1000, self.reflash_nowtime)
 68 
 69     def statistics_time(self):
 70         #统计时间文本中的总时间并保存至新文本
 71         file = self.saveFile.get()
 72         if file:
 73             size = os.path.getsize(file)
 74             if size>0:
 75                 sum = 0
 76                 with open(file,"r") as f:
 77                     for line in f.readlines():
 78                             sum +=eval(line.split()[0])
 79                 path = os.path.dirname(file)
 80                 savePath = path + '/总时间.txt'
 81                 with open(savePath,"a+") as f:
 82                     f.write(str(sum)+"\n")
 83                 messagebox.showwarning(title="成功", message="数据已保存!")
 84             else:
 85                 messagebox.showwarning(title="错误", message="时间文本数据为空!")
 86         else:
 87             messagebox.showwarning(title="错误", message="未找到时间文本!")
 88 
 89     def save(self):
 90         #刷新运行总时间并保存至文本
 91         self.end = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
 92         self.endTime.set("游戏结束时间:" + self.end)
 93         self.start = parser.parse(self.start)
 94         self.end =  parser.parse(self.end)
 95         self.sum = (self.end - self.start).total_seconds()
 96         m, s = divmod(self.sum, 60)
 97         h, m = divmod(m, 60)
 98         self.time.set("游戏运行时间:%d:%02d:%02d" % (h, m, s))
 99         with open(self.saveFile.get(), "a+") as f:
100             f.write(str(self.sum/60)+"\n")
101 
102     def is_run(self):
103         #不断刷新判断进程是否是运行状态
104         if psutil.pid_exists(self.pid):
105             self.after(1,self.is_run)
106         else:
107             self.save()
108 
109     def start_time(self,flag=None):
110         # 在save_entry中显示保存时间文本的路径,flag用于区分是在选择文件还是点击了"运行"按钮
111         if flag is None:
112             # 获取并在save_entry中显示文件路径
113             file = filedialog.askopenfilename()
114             self.saveFile.set(file)
115         else:
116         #当exe程序运行时
117             self.start = time.strftime('%Y-%m-%d %H:%M:%S')
118             self.startTime.set("游戏开始时间:" + self.start)
119             self.is_run()
120 
121     def get_pid(self,exe_file):
122         #根据程序名称获取进程号,以此判断是否为运行状态
123         win32api.ShellExecute(0, 'open',exe_file , '','',1)
124         time.sleep(0.5)
125         pl = psutil.pids()
126         f = os.path.basename(exe_file)
127         for pid in pl:
128             if psutil.Process(pid).name() != f:
129                 continue
130             else:
131                 self.pid = pid
132                 self.start_time(self.pid)
133                 """考虑到多进程问题,这里只获取匹配到的第一个pid,因为初衷是监测游戏运行时间,关闭游戏,即关闭父进程,
134                 子进程也随之关闭,所以无论匹配的是子pid还是父pid,对程序的运行时没有影响的"""
135                 break
136 
137     def run(self):
138         # 当"运行"按钮被点击以后
139         exe_file = self.exeFile.get()
140         save_file = self.saveFile.get()
141         if exe_file:
142             result1 = os.path.basename(exe_file)
143             if result1.split(".")[-1] != "exe":
144                 #并且如果选择的不是exe文件
145                 messagebox.showwarning(title="错误",message="请打开一个exe文件!")
146             else:
147                 if save_file:
148                     result2 = os.path.basename(save_file)
149                     if result2.split(".")[-1] != "txt":
150                         messagebox.showwarning(title="错误", message="请选择一个txt文件进行保存!")
151                     else:
152                         self.get_pid(exe_file)
153                 else:
154                     messagebox.showwarning(title="错误", message="请选择一个txt文件进行保存!")
155         else:
156             messagebox.showwarning(title="错误",message="未找到程序!")
157 
158 if __name__ == '__main__':
159     win = tk.Tk()
160     gui = GUI()
161     win.mainloop()

也是突然想写这么一个小程序,仓促学习了一下tkinter,有错误和需要改进的地方,还请评论指正~

 

posted @ 2020-04-06 18:23  只猫  阅读(560)  评论(0编辑  收藏  举报