一个基于Python的tkinter模块实现的游戏活动日历模拟器

  • 1、Python环境准备
  • 2、简单介绍
  • 3、源代码
  • 4、源代码及活动配置表下载

1、Python环境准备

  1. 运行该项目需要Python3以上的版本
  2. 需安装excel解析模块,命令为:pip install xlrd==1.2.0

2、简单介绍

该项目使用Python的tkinter模块编写显示界面,通过解析excel表格中的活动数据,将各个活动的触发时间、运行时间、活动名、活动类型等以直观的方式展现出来。

3、源代码

#encoding: utf-8import os, sys, time, datetime
import xlrd
import functools
from tkinter import *
from tkinter import messageboxclass ActivityBase:def __init__(self, id, name, type, cycleBeginType, actBeginTime, actEndTime, cycle, cycleContinueTime, beginSvrOpenDays, endSvrOpenDays):# 活动idself.id = id# 名称self.name = name# 活动类型self.type = type# 周期起始时间类型self.cycleBeginType = cycleBeginType# 活动开始时间self.actBeginTime = actBeginTime# 活动结束时间self.actEndTime = actEndTime# 循环周期self.cycle = cycle# 周期内持续时间self.cycleContinueTime = cycleContinueTime# 开始开服天数self.beginSvrOpenDays = beginSvrOpenDays# 结束开服天数self.endSvrOpenDays = endSvrOpenDaysdef __getOneDateZeroClockSec(self, sec):return int(time.mktime(time.strptime(time.strftime('%Y-%m-%d', time.localtime(sec)), '%Y-%m-%d')))# 获取活动首次开启时间def __getActRealBeginTime(self, initTime):#按活动开启时间算if self.cycleBeginType == 1:return self.actBeginTime#开服当天零点actBeginTime = initTime + (self.beginSvrOpenDays - 1) * 86400actBeginTime += (self.actBeginTime - self.__getOneDateZeroClockSec(self.actBeginTime))return actBeginTime# 获取活动当次循环开启时间def getCurCycleBeginTime(self, initTime, now):passDay = (now - initTime) // 86400 + 1if passDay < self.beginSvrOpenDays or passDay > self.endSvrOpenDays:return -1if now < self.actBeginTime or now > self.actEndTime:return -1actBeginTime = self.__getActRealBeginTime(initTime)cycle = self.cycle * 86400if cycle <= 0:return actBeginTimereturn (now - actBeginTime) // cycle * cycle + actBeginTime# 获取活动当次循环结束时间def getCurCycleEndTime(self, initTime,now):if self.cycleContinueTime <= 0:return self.actEndTimereturn self.getCurCycleBeginTime(initTime, now) + self.cycleContinueTimeclass ContentData:def __init__(self, id, color, name, leaveDay, type):# 活动idself.id = id# 显示颜色self.color = color# 名称self.name = name # 活动剩余时间self.leaveDay = leaveDay# 活动类型self.type = typeclass ActivityCalendarMgr:def __init__(self):self.__curDay = 0self.__initTime = 0self.__oneDay = 0self.__startDay = 0self.__curWeek = 0self.__labW = 150self.__labH = 40self.__labHNum = 18self.__bottomH = 30self.__winW = self.__labW * 7self.__winH = self.__labH * self.__labHNum + self.__bottomHself.__root = Tk()self.__labelList = list()self.__cycleBeginTypeInt = {u'活动开始时间' : 1,u'开始开服天数' : 2,u'角色创建天数' : 3}self.__actInfoList = list()#初始化def __init(self, load= True, year = None, month = None, day = None):if year != None and month != None and day != None:self.__curDay = datetime.datetime(year, month, day)else:self.__curDay = datetime.datetime.now()self.__initTime = int(time.mktime(time.strptime(self.__curDay.strftime('%Y-%m-%d'), '%Y-%m-%d')))# 设置一天为基准的变量self.__oneDay = datetime.timedelta(days=1)# 这周起始日期,即程序显示起始日期self.__startDay = self.__curDay - self.__oneDay * self.__curDay.weekday()# 当前处于第几周self.__curWeek = 0if load == True:self.__readExcel('活动配置表.xlsm', '活动配置表')self.__componentInit()self.__showContent()#读取excel数据def __readExcel(self, xls_file, sheet_name):fieldList = [u'ID', u'名称', u'类型', u'周期起始时间类型', u'活动开始时间', u'活动结束时间', u'循环周期', u'周期内持续时间', u'开始开服天数', u'结束开服天数']titleDic = dict()xls = xlrd.open_workbook(xls_file);sheet = xls.sheet_by_name(sheet_name);# 取出列名for col in range(0, sheet.ncols):title = sheet.cell_value(0, col)titleDic[title] = colfieldDic = dict()# 一行一行读出列值for row in range(1, sheet.nrows):for field in fieldList:col = titleDic[field]fieldDic.setdefault(field, []).append(sheet.cell_value(row, col))for row in range(0, sheet.nrows - 1):id = int(fieldDic[u'ID'][row])name = fieldDic[u'名称'][row]type = fieldDic[u'类型'][row]cycleBeginType = self.__cycleBeginTypeInt[fieldDic[u'周期起始时间类型'][row]]timeBuf = time.strptime(fieldDic[u'活动开始时间'][row], '%Y/%m/%d %H:%M:%S')actBeginTime = int(time.mktime(timeBuf))timeBuf = time.strptime(fieldDic[u'活动结束时间'][row], '%Y/%m/%d %H:%M:%S')actEndTime = int(time.mktime(timeBuf))if actEndTime < self.__initTime:continuetoIntValue = lambda x : 0 if x == '' else int(x)cycle = toIntValue(fieldDic[u'循环周期'][row])cycleContinueTime = toIntValue(fieldDic[u'周期内持续时间'][row])beginSvrOpenDays = toIntValue(fieldDic[u'开始开服天数'][row])endSvrOpenDays = toIntValue(fieldDic[u'结束开服天数'][row])actInfo = ActivityBase(id, name, type, cycleBeginType, actBeginTime, actEndTime, cycle, cycleContinueTime, beginSvrOpenDays, endSvrOpenDays)self.__actInfoList.append(actInfo)#翻页def __turnPage(self, num):if num < 0 and self.__curWeek <= 0:returnself.__curWeek += num#调用一下刷新内容self.__showContent()#切换开服日期def __changeOpenDay(self, t1, t2, t3):year = int(t1.get().strip())month = int(t2.get().strip())day = int(t3.get().strip())try:date = datetime.datetime(year, month, day)except:messagebox.showwarning(u'警示', u'输入日期 %d/%d/%d 不合法'%(year, month, day))self.__root.focus_force()returnself.__init(False, year, month, day)#按键输入捕获def __keyPressBind(self, e, t1, t2, m):#lambda e: e if e.keycode != 299 and e.char in set('0123456789') else 'break'if (e.keycode == 8     #Spaceor e.keycode == 9  #Tabor e.keycode == 35 #Endor e.keycode == 36 #Homeor e.keycode == 46 #Delete):passelif e.keycode == 37: #Leftif t1 != None and e.widget.index(INSERT) == 0:t1.focus_set()t1.icursor(END)elif e.keycode == 39: #Rightif t2 != None and e.widget.index(INSERT) == len(e.widget.get().strip()):t2.focus_set()t2.icursor(0)elif e.char in set('0123456789'):num = len(e.widget.get().strip())flag = e.widget.select_present()#数据输入满了,偏移光标(讨巧使用了模拟按下TAB键操作)if t2 != None and flag != True and num == m - 1:t2.focus_set()t2.select_range(0, END)t2.icursor(END)if flag != True and num >= m:return 'break'else:return 'break'return ''#ctrl+a捕获def __selectAllBind(self, e):e.widget.select_range(0, END)e.widget.icursor(END)return 'break'#组件初始化def __componentInit(self):textHegiht = self.__bottomH - 3startX = 458text1Weight = 32text2Weight = 18separateWeight = 10text1 = Entry(self.__root, background = 'white', borderwidth = 1, takefocus = True)text1.insert(0, datetime.date.today().year)text1.bind('<Control-a>', self.__selectAllBind)text1.bind('<Control-A>', self.__selectAllBind)text1.place(x = startX, y = 0, width = text1Weight, height = textHegiht)separate1 = Text(self.__root, background = 'white', borderwidth = 0)separate1.insert(INSERT, '-')separate1.config(state = DISABLED)separate1.place(x = startX + text1Weight, y = 6, width = separateWeight, height = self.__bottomH)text2 = Entry(self.__root, background = 'white', borderwidth = 1, takefocus = True)text2.insert(0, datetime.date.today().month)text2.bind('<Control-a>', self.__selectAllBind)text2.bind('<Control-A>', self.__selectAllBind)text2.place(x = startX + text1Weight + separateWeight, y = 0, width = text2Weight, height = textHegiht)separate2 = Text(self.__root, background = 'white', borderwidth = 0)separate2.insert(INSERT, '-')separate2.config(state = DISABLED)separate2.place(x = startX + text1Weight + text2Weight + separateWeight, y = 6, width = separateWeight, height = self.__bottomH)text3 = Entry(self.__root, background = 'white', borderwidth = 1, takefocus = True)text3.insert(0, datetime.date.today().day)text3.bind('<Control-a>', self.__selectAllBind)text3.bind('<Control-A>', self.__selectAllBind)text3.place(x = startX + text1Weight + text2Weight + separateWeight * 2, y = 0, width = text2Weight, height = textHegiht)#输入框绑定按键行为text1.bind('<KeyPress>', lambda event : self.__keyPressBind(event, None, text2, 4))text2.bind('<KeyPress>', lambda event : self.__keyPressBind(event, text1, text3, 2))text3.bind('<KeyPress>', lambda event : self.__keyPressBind(event, text2, None, 2))#切换开服日期按钮button = Button(self.__root, text = '切换开服日期', command = lambda : self.__changeOpenDay(text1, text2, text3), bg = 'white', activebackground = 'white')button.place(x = startX + text1Weight + text2Weight * 2 + separateWeight * 2 + 10, y = 0, width = 78, height = textHegiht)#绑定翻页行为(键盘左右键、鼠标滚轮)self.__root.bind('<Left>', lambda event : self.__turnPage(-1) if event.widget != text1 and event.widget != text2 and event.widget != text3 else 'break')self.__root.bind('<Right>', lambda event : self.__turnPage(1) if event.widget != text1 and event.widget != text2 and event.widget != text3 else 'break')self.__root.bind('<MouseWheel>', lambda event : self.__turnPage(-1) if event.delta > 0 else self.__turnPage(1))#绑定聚焦行为self.__root.bind('<Button-1>', lambda event : self.__root.focus_set() if event.widget != text1 and event.widget != text2 and event.widget != text3 else 'break')def __showContent(self):# 边框类型(relief参数: flat(默认), groove, raised, ridge, solid, sunken)frame = 'groove'# 边框宽度(像素)borderwidth = 1#1.清屏(只执行一次)if len(self.__labelList) == 0:for y_index in range(self.__labHNum):for x_index in range(7):label = Label(self.__root, bg = 'white', relief = frame, bd = borderwidth)label.place(x = self.__labW * x_index, y = self.__labH * y_index + self.__bottomH, width = self.__labW, height = self.__labH)#2.释放旧标签内存for l in self.__labelList:l.destroy()self.__labelList = list()#3.显示顶部栏labels = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日']for index in range(7):day = self.__startDay + self.__oneDay * (self.__curWeek * 7 + index)title = str(labels[index]) + '\n' + day.strftime('%Y-%m-%d')color = 'grey'if day == self.__curDay:color = 'yellow'label = Label(self.__root, bg = color, text = title, relief = frame, bd = borderwidth)label.place(x = + self.__labW * index, y = self.__bottomH, width = self.__labW, height = self.__labH)self.__labelList.append(label)#4.内容栏数据提取fieldSet = [set() for row in range(7)]contentList = [list() for row in range(7)]for index in range(7):day = self.__startDay + self.__oneDay * (self.__curWeek * 7 + index)color = 'SpringGreen'if day < self.__curDay:continueelif day == self.__curDay:color = 'yellow'for actInfo in self.__actInfoList:# 强行给 curTime 加20个小时,兼容特殊活动curTime = int(time.mktime(time.strptime(day.strftime('%Y-%m-%d'), '%Y-%m-%d'))) + 72000beginTime = actInfo.getCurCycleBeginTime(self.__initTime, curTime)if beginTime == -1:continueendTime = actInfo.getCurCycleEndTime(self.__initTime, curTime)if beginTime <= curTime and curTime <= endTime:if actInfo.id in fieldSet[index]:continueleaveDay = (endTime - curTime) // 86400 + 1if index + leaveDay > 7:leaveDay = 7 - indexcontentList[index].append(ContentData(actInfo.id, color, actInfo.name, int(leaveDay), actInfo.type))for i in range(leaveDay):fieldSet[index + i].add(actInfo.id)#5.数据刷新显示yIndex = 0for index in range(7):#先排序一下,先比活动剩余时间,时间越长越靠前;再比活动id,id越小越靠前contentList[index].sort(key = functools.cmp_to_key(lambda x, y : x.leaveDay - y.leaveDay if x.leaveDay != y.leaveDay else y.id - x.id), reverse = True)for data in contentList[index]:yIndex += 1if yIndex <= self.__labHNum:showText = u'%s\n%d(%s)'%(data.name, data.id, data.type)label = Label(self.__root, bg = data.color, text = showText, relief = frame, bd = borderwidth)label.place(x = + self.__labW * index, y = yIndex * self.__labH + 5 + self.__bottomH, width = self.__labW * data.leaveDay, height = self.__labH - 10)self.__labelList.append(label)#6.显示上限提示if yIndex > self.__labHNum:messagebox.showwarning(u'警示', u'本周有%d个活动,显示上限为%d个,超出部分不显示'%(yIndex, self.__labHNum - 1))self.__root.focus_force()returndef run(self):#显示活动日历基本框架self.__root.title('活动日历')self.__root.geometry(str(self.__winW) + 'x' + str(self.__winH) + '+400+100')self.__root.config(background = 'white')self.__root.resizable(False, False)#初始化数据self.__init()self.__root.mainloop()if __name__== '__main__':mgr = ActivityCalendarMgr()mgr.run()

4、源代码及活动配置表下载

下载地址:游戏活动日历模拟器Python源码

一个基于Python的tkinter模块实现的游戏活动日历模拟器相关推荐

  1. 基于 Python 的 tkinter 模块制作的名人名言查询工具

    简介:本文主要介绍如何用 Python 内置的 tkinter 写一个查询工具. 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手. 很多 ...

  2. 基于python的Tkinter模块和Threading模块制作的用于班级/多人抽签的小程序

    程序思路: 先录入需要进行抽签的所有人的名字数据,然后进行随机打乱,显示随机打乱的结果在标签上,通过增加Threading模块控制抽签这个线程的进行与停止. 在本例中,我增加了当抽到之前已经抽到的人时 ...

  3. 用python设计学生管理系统_基于python和tkinter实现的一个简单的学生信息管理系统...

    一个简单的学生信息管理系统基于python和tkinter 1.需求分析1.大学生信息管理系统使用tkinter接口创建一个窗口.使界面更漂亮.2. 实现与数据库的连接,教师和学生的信息可以保存或读取 ...

  4. python os模块安装方法_基于python中pygame模块的Linux下安装过程(详解)

    一.使用pip安装Python包 大多数较新的Python版本都自带pip,因此首先可检查系统是否已经安装了pip.在Python3中,pip有时被称为pip3. 1.在Linux和OS X系统中检查 ...

  5. 生长算法实现点集的三角剖分(Python(Tkinter模块))

    生长算法实现点集的三角剖分( Python(Tkinter模块)) 关于三角剖分 假设V是二维实数域上的有限点集,边e是由点集中的点作为端点构成的封闭线段, E为e的集合.那么该点集V的一个三角剖分T ...

  6. linux下载tkinter模块,Linux升级Python提示Tkinter模块找不到解决

    一.安装tkinter 在Linux中python默认是不安装Tkinter模块, [root@li250- ~]# python Python 2.6. (r266:, Feb , ::) [GCC ...

  7. python中label有什么用_对Python中TKinter模块中的Label组件实例详解

    Python2.7.4 OS-W7x86 1. 简介 Label用于在指定的窗口中显示文本和图像.最终呈现出的Label是由背景和前景叠加构成的内容. Label组件定义函数:Label(master ...

  8. Python中Tkinter模块的Canvas控件绘制jpg图片到指定区域

      准备在Python的Tkinter模块中用Canvas绘制如下形式的工艺卡片(图片来自参考文献5,原图来自参考文献4),但是在绘制图形时遇到两个问题,特此记录如下: jpg图片无法读取   Can ...

  9. python云盘私有云_GitHub - 0x2642/Umi-Chest: 一个基于python的私有云实验项目

    Umi-Chest 一个基于angular 4的单页面舰娘百科App 关于项目名是因为kuma一直找不到好的名字,因为联想到海,然后我喜欢海爷,所以本来想叫海爷百宝箱什么的(一个舰娘的App你叫海爷百 ...

最新文章

  1. Android注解使用之ButterKnife 8.0注解使用介绍
  2. java 门面模式_Java门面模式
  3. 使用GCC生成无格式二进制文件(plain binary files)
  4. 注意满足循环终止条件时counter是否仍在+1(记洛谷P1035WA的经历,Java语言描述)
  5. gentoo/funtoo 环境配置使用 valgrind
  6. 开发跨平台应用解决方案-uniapp 真心不错,支持一波
  7. Android RecyclerView拖放
  8. Rust之字符串,元组,数组,切片,打印优化
  9. 如何才能真正的学会设计模式
  10. python控制小爱同学_小爱同学控制电脑开机 - IT客栈
  11. 第6章 DataNode
  12. “感受野”的直观理解
  13. Tomcat7集群共享Session 基于redis进行统一管理
  14. 2021-08-07 STM32F103 Buffer SPI Transfer 缓冲通讯
  15. windows server 2008服务器管理器,添加IIS配置(2012同理)
  16. Oo0代码混淆实现方法
  17. token过期后刷新token并重新发起请求
  18. 分布式本地缓存刷新方案
  19. ios定位权限plist_最新版ios权限描述文字plist的权限描述文字...
  20. C#打开第三方应用程序

热门文章

  1. 如何用Verilog HDL设计显示译码器
  2. 高性能Linux服务器构建实战 服务器安全运维
  3. 搭建一套安防监控系统RTSP/Onvif网络摄像头视频流媒体服务器需要哪些核心要素?
  4. java实现冗余校验_Java中循环冗余校验(CRC32)的实现
  5. C语言异或操作详解(小小异或,大大作用~)
  6. 林子雨案例----淘宝伪数据分析
  7. sun java applet_Java Applet 基础
  8. matlab 求信噪比
  9. uniapp小程序自定义loding,通过状态管理配置全局使用
  10. Unity3D地形挖坑