一、背景
在上一篇文章中(Python制作排班小工具【一】),已经编写了小工具的排班逻辑,本篇文章将实现小工具的GUI界面。
那么先粗略画一张UI示意图,GUI界面代码就按照这张图来编写:
二、代码实现
使用ttkbootstrap:
1.创建“生成排班”和“查看记录”两个Notebook
2.将Label标签,Entry输入框,Button按钮、Checkbutton复选按钮添加到Notebook中
3.因“参与排班人员姓名”文本内容可能比较长,故使用Text文本框
4.“生成的排班表”以及“查看记录”Notebook均使用Text来展示文本内容
5.在底部添加了当前时间的展示Label,能够实时更新
6.Notebook、“查看记录”的展示Text文本框以及当前时间Label使用pack布局方式,其余均使用grid布局方式
import datetime
import time
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
from tkinter import DISABLED
class GUI:
def __init__(self, master):
"""排排班GUI"""
self.root = master
self.name = ttk.StringVar() # 生成StringVar对象,以保存输入框中的内容--参与排班人员姓名
self.each_group_num = ttk.StringVar() # 每日值班人数
self.group_num = ttk.StringVar() # 值班组数量
self.variable = ttk.BooleanVar() # 删除人员配置开关设置--布尔值
self.create_page()
self.update_time()
def create_page(self):
"""创建页面元素"""
# # ------------------------------------标签页控件------------------------------------#
# 创建标签页控件
tabcontrol = ttk.Notebook(self.root)
# 【生成排班】标签
tab1 = ttk.Frame(tabcontrol)
tabcontrol.add(tab1, text='生成排班')
# 【查看记录】标签
tab2 = ttk.Frame(tabcontrol)
tabcontrol.add(tab2, text="查看记录")
# 打包标签控件
tabcontrol.pack(expand=1, fill=BOTH)
# # ------------------------------------标签页控件------------------------------------#
# # ------------------------------------生成排班------------------------------------#
# 参与排班人员姓名标签
name_label = ttk.Label(tab1, text="参与排班人员姓名:", bootstyle=PRIMARY)
name_label.grid(row=0, column=0, pady=5) # 使用grid布局(网格布局方式)
# 参与排班人员姓名文本框
self.name_input = ttk.Text(tab1, width=23, height=2, wrap=ttk.WORD)
self.name_input.grid(row=0, column=1, columnspan=3, pady=5)
# 每日值班人数标签
each_group_num_label = ttk.Label(tab1, text="每日值班人数:", bootstyle=PRIMARY)
each_group_num_label.grid(row=1, column=0, pady=5, sticky=E)
# 每日值班人数输入框
each_group_num_input = ttk.Entry(tab1, textvariable=self.each_group_num, width=5)
each_group_num_input.grid(row=1, column=1, pady=5)
# 值班组数量标签
group_num_label = ttk.Label(tab1, text="值班组数量:", bootstyle=PRIMARY)
group_num_label.grid(row=1, column=2, pady=5, padx=5, sticky=E)
# 值班组数量输入框
group_num_input = ttk.Entry(tab1, textvariable=self.group_num, width=5)
group_num_input.grid(row=1, column=3, pady=5)
# 生成排班按钮
generate_button = ttk.Button(tab1, text="生成排班", bootstyle=OUTLINE, command=self.generate)
generate_button.grid(row=2, column=0, pady=5)
# 删除人员配置开关设置按钮
switch_button = ttk.Checkbutton(tab1, variable=self.variable, offvalue=False, onvalue=True,
command=self.delete_switch, bootstyle="round-toggle")
switch_button.grid(row=2, column=1, pady=5)
# 删除人员配置按钮
self.del_button = ttk.Button(tab1, text="删除人员配置", bootstyle="danger-outline", command=self.delete,
state=DISABLED)
self.del_button.grid(row=2, column=2, columnspan=2, pady=5)
# 生成的排班表展示文本框
self.show_text = ttk.Text(tab1, wrap=ttk.WORD, width=39, height=10, state=DISABLED) # 默认text文本框不可编辑
self.show_text.grid(row=3, column=0, columnspan=4)
# # ------------------------------------生成排班------------------------------------#
# # ------------------------------------查看记录------------------------------------#
# 生成的排班记录展示文本框
self.show_record_text = ttk.Text(tab2, wrap=ttk.WORD, width=39, height=16, state=DISABLED)
self.show_record_text.pack(expand=1, fill=BOTH)
# # ------------------------------------查看记录------------------------------------#
# # ------------------------------------当前时间------------------------------------#
# 当前时间标签
self.current_time_label = ttk.Label(self.root, bootstyle=PRIMARY)
self.current_time_label.pack()
# # ------------------------------------当前时间------------------------------------#
def generate(self):
"""
TODO:点击【生成排班】按钮时对应的事件
:return:
"""
pass
def delete_switch(self):
"""
TODO:点击【删除人员配置开关设置】按钮时对应的事件
:return:
"""
pass
def delete(self):
"""
TODO:点击【删除人员配置】按钮时对应的事件
:return:
"""
pass
def update_time(self):
"""
获取当前时间和本年第几周,每隔1s更新
:return:
"""
current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
week_num = int(time.strftime("%W")) + 1
self.current_time_label.config(text=f"{current_time} 第{week_num}周")
self.current_time_label.after(1000, self.update_time)
if __name__ == "__main__":
root = ttk.Window(
title="排排班", # 窗口标题
themename="superhero" # 主题
)
root.place_window_center() # 设置窗口居中(左上角坐标在屏幕中间?)
root.iconbitmap('icon.ico') # 更改GUI图标
root.resizable(width=False, height=False) # 设置窗口大小不可变
GUI(root) # 展示GUI界面
root.mainloop() # 进入消息循环
运行结果:
三、结语
1.ttkbootstrap第三方库需要单独安装,GUI图标只支持.ico格式
2.可通过Window的themename参数切换主题样式,参考官方文档
2.页面元素的布局设计不太科学,基本是试出来的
3.仅展示页面元素,暂未编写按钮对应的事件