景点门票销售管理系统 基于 python实现gui界面 之 笔记
1、建立数据库、建表、加外键约束、建触发器
此处106行
CREATE DATABASE IF NOT EXISTS `景点门票销售管理系统` DEFAULT CHARACTER SET utf8;USE `景点门票销售管理系统`;/*Table structure for table `游客信息` */DROP TABLE IF EXISTS `游客信息`;CREATE TABLE `游客信息` (`游客账号` CHAR(20) NOT NULL,`游客密码` CHAR(20) NOT NULL,`游客姓名` CHAR(20) DEFAULT NULL,`游客性别` CHAR(20) DEFAULT NULL,`联系电话` CHAR(20) DEFAULT NULL,`注册时间` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (`游客账号`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;/*Data for the table `游客信息` */INSERT INTO `游客信息`(`游客账号`,`游客密码`,`游客姓名`,`游客性别`,`联系电话`,`注册时间`) VALUES ('11','11','Li','男','112','2021-11-15 20:05:13');/*Table structure for table `管理员信息` */DROP TABLE IF EXISTS `管理员信息`;CREATE TABLE `管理员信息` (`管理员账号` CHAR(20) NOT NULL,`管理员密码` CHAR(20) NOT NULL,`管理员姓名` CHAR(20) NOT NULL,`管理员性别` CHAR(20) DEFAULT NULL,`联系电话` CHAR(20) DEFAULT NULL,`工号` CHAR(20) NOT NULL,PRIMARY KEY (`管理员账号`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;/*Data for the table `管理员信息` */INSERT INTO `管理员信息`(`管理员账号`,`管理员密码`,`管理员姓名`,`管理员性别`,`联系电话`,`工号`) VALUES ('123451','123451','杨华','男','111112','10081'),('123452','123452','李华','男','10081','111113');/*Table structure for table `订票信息` */DROP TABLE IF EXISTS `订票信息`;CREATE TABLE `订票信息` (`订票编号` INT(11) NOT NULL AUTO_INCREMENT,`游客账号` CHAR(20) DEFAULT NULL,`身份证号` CHAR(20) DEFAULT NULL,`联系电话` CHAR(20) DEFAULT NULL,`订票数量` CHAR(20) DEFAULT NULL,`应付金额` CHAR(20) DEFAULT NULL,`操作时间` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (`订票编号`),KEY `游客账号` (`游客账号`),CONSTRAINT `订票信息_ibfk_1` FOREIGN KEY (`游客账号`) REFERENCES `游客信息` (`游客账号`)
) ENGINE=INNODB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8;/*Data for the table `订票信息` */INSERT INTO `订票信息`(`订票编号`,`游客账号`,`身份证号`,`联系电话`,`订票数量`,`应付金额`,`操作时间`) VALUES (13,'11','11','111','3','120','2021-11-15 20:32:16');/*Table structure for table `退票信息` */DROP TABLE IF EXISTS `退票信息`;CREATE TABLE `退票信息` (`订票编号` INT(11) NOT NULL,`游客账号` CHAR(20) DEFAULT NULL,`身份证号` CHAR(20) DEFAULT NULL,`联系电话` CHAR(20) DEFAULT NULL,`退票数量` INT(20) DEFAULT NULL,`退还金额` INT(20) DEFAULT NULL,`操作时间` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (`订票编号`),KEY `游客账号` (`游客账号`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;/*Data for the table `退票信息` *//* Trigger structure for table `订票信息` */DELIMITER $$
DROP TRIGGER IF EXISTS `tmp1_insert` $$
CREATE TRIGGER `tmp1_insert`
BEFORE INSERT ON `订票信息`
FOR EACH ROW
BEGINSET new.`应付金额`= new.`订票数量`*60;
END $$
DELIMITER ;/* Trigger structure for table `订票信息` */DELIMITER $$
DROP TRIGGER IF EXISTS `insert_date` $$
CREATE TRIGGER `insert_date`
BEFORE DELETE ON `订票信息`
FOR EACH ROW
BEGIN#insert `退票信息` as t set new.`订票编号`= old.`订票编号`,new.`数量`= old.`数量`,new.`金额`= old.`金额` ;#insert `退票信息` set `订票编号`=old.`订票编号` where `订票编号`=old.`订票编号`;INSERT INTO `退票信息`(`订票编号`,`游客账号`,`身份证号`,`联系电话`,`退票数量`,`退还金额`) VALUES(old.`订票编号`,old.`游客账号`,old.`身份证号`,old.`联系电话`,old.`订票数量`,old.`应付金额`);
END $$
DELIMITER ;
2、实现交互界面代码,有待改进
此处2023行
#加油
import pymysql
from tkinter import ttk
import tkinter as tk
import tkinter.font as tkFont
from tkinter import * # 图形界面库
import tkinter.messagebox as messagebox # 弹窗#开始页面
class StartPage:def __init__(self, parent_window):#parent_window.update()parent_window.destroy() # 销毁子界面self.window = tk.Tk() # 初始框的声明self.window.title('景点门票销售管理系统')self.window.geometry('900x900') # 这里的乘是小xself.window.geometry('+330+0')label = Label(self.window, text="景点门票销售管理系统", font=("Verdana", 40))label.pack(pady=100) # pady=100 界面的高度Button(self.window, text="管理员登陆", font=tkFont.Font(size=25), command=lambda: AdminPage(self.window), width=60, height=2,fg='white', bg='gray', activebackground='black', activeforeground='white').pack()Button(self.window, text="游客登陆", font=tkFont.Font(size=25), command=lambda: TourPage(self.window), width=60,height=2,fg='white', bg='gray', activebackground='black', activeforeground='white').pack()Button(self.window, text="用户注册", font=tkFont.Font(size=25), command=lambda: SignPage(self.window), width=60,height=2,fg='white', bg='gray', activebackground='black', activeforeground='white').pack() Button(self.window, text="关于", font=tkFont.Font(size=25), command=lambda: AboutPage(self.window), width=60, height=2,fg='white', bg='gray', activebackground='black', activeforeground='white').pack()Button(self.window, text='退出系统', height=2, font=tkFont.Font(size=25), width=60, command=self.window.destroy,fg='white', bg='gray', activebackground='black', activeforeground='white').pack()self.window.mainloop() # 主消息循环#管理员登陆页面
class AdminPage:def __init__(self, parent_window):parent_window.destroy() # 销毁主界面self.window = tk.Tk() # 初始框的声明self.window.title('管理员登陆页面')self.window.geometry('900x900') # 这里的乘是小xself.window.geometry('+330+0')label = tk.Label(self.window, text='管理员登陆', bg='green', font=('Verdana', 30), width=40, height=3)label.pack()Label(self.window, text='管理员账号:', font=tkFont.Font(size=20)).pack(pady=25)self.admin_username = tk.Entry(self.window, width=30, font=tkFont.Font(size=20), bg='Ivory')self.admin_username.pack()Label(self.window, text='管理员密码:', font=tkFont.Font(size=20)).pack(pady=25)self.admin_pass = tk.Entry(self.window, width=30, font=tkFont.Font(size=20), bg='Ivory', show='*')self.admin_pass.pack()Button(self.window, text="登陆", width=10, font=tkFont.Font(size=15), command=self.login).pack(pady=40)Button(self.window, text="返回", width=10, font=tkFont.Font(size=15), command=self.back).pack()self.window.protocol("WM_DELETE_WINDOW", self.back) # 捕捉右上角关闭点击self.window.mainloop() # 进入消息循环def login(self):#从界面获取的数据print(str(self.admin_username.get()))print(str(self.admin_pass.get()))admin_pass = None# 数据库操作 查询管理员表con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8') # 打开数据库连接cursor = con.cursor() # 使用cursor()方法获取操作游标sql = "SELECT * FROM 管理员信息 WHERE 管理员账号 = '%s'" % (self.admin_username.get()) # SQL 查询语句try:# 执行SQL语句cursor.execute(sql)# 获取所有记录列表results = cursor.fetchall()for row in results:admin_id = row[0]admin_pass = row[1]# 打印结果print("admin_id=%s,admin_pass=%s" % (admin_id, admin_pass))except:print("Error: unable to fecth data")messagebox.showinfo('警告!', '用户名或密码不正确!')con.close() # 关闭数据库连接print("正在登陆管理员管理界面")#从界面获取的数据print("self",self.admin_pass)#数据库里的数据print("local",admin_pass)# 判断密码,正确则进入管理员操作界面if self.admin_pass.get() == admin_pass:TicketMessage(self.window) else:messagebox.showinfo('警告!', '用户名或密码不正确!')def back(self):StartPage(self.window) # 显示主窗口 销毁本窗口#游客登陆页面
class TourPage:def __init__(self, parent_window):parent_window.destroy() # 销毁主界面self.window = tk.Tk() # 初始框的声明self.window.title('游客登陆')self.window.geometry('900x900') # 这里的乘是小xself.window.geometry('+330+0')label = tk.Label(self.window, text='游客登陆', bg='green', font=('Verdana', 30), width=40, height=3)label.pack()Label(self.window, text='游客账号:', font=tkFont.Font(size=20)).pack(pady=25)self.tour_id = tk.Entry(self.window, width=30, font=tkFont.Font(size=20), bg='Ivory')self.tour_id.pack()Label(self.window, text='游客密码:', font=tkFont.Font(size=20)).pack(pady=25)self.tour_pass = tk.Entry(self.window, width=30, font=tkFont.Font(size=20), bg='Ivory', show='*')self.tour_pass.pack()Button(self.window, text="登陆", width=10, font=tkFont.Font(size=15), command=self.login).pack(pady=40)Button(self.window, text="返回", width=10, font=tkFont.Font(size=15), command=self.back).pack()self.window.protocol("WM_DELETE_WINDOW", self.back) # 捕捉右上角关闭点击self.window.mainloop() # 进入消息循环def login(self):print(str(self.tour_id.get()))print(str(self.tour_pass.get()))tou_pass = None# 数据库操作 查询管理员表con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8') # 打开数据库连接cursor = con.cursor() # 使用cursor()方法获取操作游标sql = "SELECT * FROM 游客信息 WHERE 游客账号 = '%s'" % (self.tour_id.get()) # SQL 查询语句try:# 执行SQL语句cursor.execute(sql)# 获取所有记录列表results = cursor.fetchall()for row in results:tou_id = row[0]tou_pass = row[1]# 打印结果print("tou_id=%s,tou_pass=%s" % (tou_id, tou_pass))except:print("Error: unable to fecth data")messagebox.showinfo('警告!', '用户名或密码不正确!')con.close() # 关闭数据库连接print("正在登陆.....")print("self", self.tour_pass.get())print("local", tou_pass)# 进入门票信息查看界面if self.tour_pass.get() == tou_pass:TourKit(self.window) else:messagebox.showinfo('警告!', '用户名或密码不正确!')def back(self):StartPage(self.window) # 显示主窗口 销毁本窗口#用户注册页面
class SignPage:def __init__(self, parent_window):#parent_window.update()parent_window.destroy() # 销毁子界面self.window = tk.Tk() # 初始框的声明self.window.title('注册')self.window.geometry('900x900') # 这里的乘是小xself.window.geometry('+330+0')label = Label(self.window, text="注册页面", font=("Verdana", 40))label.pack(pady=100) # pady=100 界面的长度Button(self.window, text="管理员注册", font=tkFont.Font(size=25), command=lambda: AdminSign(self.window), width=60, height=2,fg='white', bg='gray', activebackground='black', activeforeground='white').pack()Button(self.window, text="游客注册", font=tkFont.Font(size=25), command=lambda: TourSign(self.window), width=60,height=2,fg='white', bg='gray', activebackground='black', activeforeground='white').pack()Button(self.window, text="返回首页", font=tkFont.Font(size=25), command= self.back, width=60,height=2,fg='white', bg='gray', activebackground='black', activeforeground='white').pack()self.window.protocol("WM_DELETE_WINDOW", self.back) # 捕捉右上角关闭点击self.window.mainloop() # 进入消息循环def back(self):StartPage(self.window) # 显示主窗口 销毁本窗口#管理员
#管理员注册操作
class AdminSign:def __init__(self, parent_window):parent_window.destroy() # 销毁主界面self.window = tk.Tk() # 初始框的声明self.window.title('管理员注册页面')self.window.geometry('900x900') # 这里的乘是小xself.window.geometry('+330+0')self.admin_userid = [] #账号self.admin_pass = [] #密码self.admin_name = [] #姓名self.admin_sex = [] #性别self.admin_phone = [] #电话self.admin_jid = [] #工号# 打开数据库连接con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标sql = "SELECT * FROM 管理员信息" # SQL 查询语句try:# 执行SQL语句cursor.execute(sql)# 获取所有记录列表results = cursor.fetchall()for row in results:self.admin_userid.append(row[0])self.admin_pass.append(row[1])self.admin_name.append(row[2])self.admin_sex.append(row[3])self.admin_phone.append(row[4])self.admin_jid.append(row[5])# print(self.admin_userid)# print(self.admin_name)# print(self.admin_sex)# print(self.admin_jid)except:print("Error: unable to fetch data")messagebox.showinfo('警告!', '数据库连接失败!')con.close()# 关闭数据库连接self.var_userid = StringVar() # 声明管理员账号self.var_pass = StringVar() # 声明管理员密码self.var_name = StringVar() # 声明管理员姓名self.var_sex = StringVar() # 声明管理员性别self.var_phone = StringVar() # 声明管理员电话self.var_jid = StringVar() # 声明管理员工号label = tk.Label(self.window, text='管理员注册', bg='green', font=('Verdana', 30), width=40, height=3)label.pack()Label(self.window, text='账号:', font=tkFont.Font(size=15)).pack(pady=10,anchor='w')self.var_userid = tk.Entry(self.window, width=40, font=tkFont.Font(size=20), bg='Ivory')self.var_userid.pack(anchor='nw')Label(self.window, text='密码:', font=tkFont.Font(size=15)).pack(pady=10,anchor='w')self.var_pass = tk.Entry(self.window, width=40, font=tkFont.Font(size=20), bg='Ivory', show='*')self.var_pass.pack(anchor='nw')Label(self.window, text='姓名:', font=tkFont.Font(size=15)).pack(pady=10,anchor='w')self.var_name = tk.Entry(self.window, width=40, font=tkFont.Font(size=20), bg='Ivory')self.var_name.pack(anchor='nw')Label(self.window, text='性别:', font=tkFont.Font(size=15)).pack(pady=10,anchor='w')self.var_sex = tk.Entry(self.window, width=40, font=tkFont.Font(size=20), bg='Ivory')self.var_sex.pack(anchor='nw')Label(self.window, text='联系电话:', font=tkFont.Font(size=15)).pack(pady=10,anchor='w')self.var_phone = tk.Entry(self.window, width=40, font=tkFont.Font(size=20), bg='Ivory')self.var_phone.pack(anchor='nw')Label(self.window, text='工号:', font=tkFont.Font(size=15)).pack(pady=10,anchor='w')self.var_jid = tk.Entry(self.window, width=40, font=tkFont.Font(size=20), bg='Ivory')self.var_jid.pack(anchor='nw')Button(self.window, text="注册", width=20, font=tkFont.Font(size=15), command=self.new_row).pack(pady=20)Button(self.window, text="返回", width=20, font=tkFont.Font(size=15), command=self.back).pack(pady=20)self.window.protocol("WM_DELETE_WINDOW", self.back) # 捕捉右上角关闭点击self.window.mainloop() # 进入消息循环def new_row(self):#从界面获取的数据print(self.var_userid.get())print(self.admin_userid)if str(self.var_userid.get()) in self.admin_userid:messagebox.showinfo('警告!', '该用户已存在!')elif (len(str(self.var_phone.get())) > 15) or (len(str(self.var_phone.get())) < 7):messagebox.showinfo('警告!', '请输入正确的电话号码!')else:if self.var_userid.get() != '' and self.var_pass.get() != '' and self.var_name.get() != '' and self.var_sex.get() != '' and self.var_phone.get() != '' and self.var_jid.get() != '':# 打开数据库连接con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标sql = "INSERT INTO 管理员信息(管理员账号,管理员密码,管理员姓名,管理员性别,联系电话,工号) \VALUES ('%s', '%s', '%s', '%s', '%s', '%s')" % \(self.var_userid.get(), self.var_pass.get(),self.var_name.get(), self.var_sex.get(),self.var_phone.get(), self.var_jid.get()) # SQL 插入语句try:cursor.execute(sql) # 执行sql语句con.commit() # 提交到数据库执行except:con.rollback() # 发生错误时回滚messagebox.showinfo('警告!', '数据库连接失败!')con.close() # 关闭数据库连接self.admin_userid.append(self.var_userid.get())self.admin_pass.append(self.var_pass.get())self.admin_name.append(self.var_name.get())self.admin_sex.append(self.var_sex.get())self.admin_phone.append(self.var_phone.get())self.admin_jid.append(self.var_jid.get())messagebox.showinfo('提示!', '注册成功!')else:messagebox.showinfo('警告!', '请填写正确的信息')def back(self):StartPage(self.window) # 显示主窗口 销毁本窗口#游客
# 游客注册界面
class TourSign:def __init__(self, parent_window):parent_window.destroy() # 销毁主界面self.window = tk.Tk() # 初始框的声明self.window.title('游客注册页面')self.window.geometry('900x900') # 这里的乘是小xself.window.geometry('+330+0')self.admin_userid = [] #账号self.admin_pass = [] #密码self.admin_name = [] #姓名self.admin_sex = [] #性别self.admin_phone = [] #电话# 打开数据库连接con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标sql = "SELECT * FROM 游客信息" # SQL 查询语句try:# 执行SQL语句cursor.execute(sql)# 获取所有记录列表results = cursor.fetchall()for row in results:self.admin_userid.append(row[0])self.admin_pass.append(row[1])self.admin_name.append(row[2])self.admin_sex.append(row[3])self.admin_phone.append(row[4])except:print("Error: unable to fetch data")messagebox.showinfo('警告!', '数据库连接失败!')con.close()# 关闭数据库连接self.var_userid = StringVar() # 声明管理员账号self.var_pass = StringVar() # 声明管理员密码self.var_name = StringVar() # 声明管理员姓名self.var_sex = StringVar() # 声明管理员性别self.var_phone = StringVar() # 声明管理员电话label = tk.Label(self.window, text='游客注册', bg='green', font=('Verdana', 30), width=40, height=3)label.pack()Label(self.window, text='账号:', font=tkFont.Font(size=15)).pack(pady=10,anchor='w')self.var_userid = tk.Entry(self.window, width=40, font=tkFont.Font(size=20), bg='Ivory')self.var_userid.pack(anchor='nw')Label(self.window, text='密码:', font=tkFont.Font(size=15)).pack(pady=10,anchor='w')self.var_pass = tk.Entry(self.window, width=40, font=tkFont.Font(size=20), bg='Ivory', show='*')self.var_pass.pack(anchor='nw')Label(self.window, text='姓名:', font=tkFont.Font(size=15)).pack(pady=10,anchor='w')self.var_name = tk.Entry(self.window, width=40, font=tkFont.Font(size=20), bg='Ivory')self.var_name.pack(anchor='nw')Label(self.window, text='性别:', font=tkFont.Font(size=15)).pack(pady=10,anchor='w')self.var_sex = tk.Entry(self.window, width=40, font=tkFont.Font(size=20), bg='Ivory')self.var_sex.pack(anchor='nw')Label(self.window, text='联系电话:', font=tkFont.Font(size=15)).pack(pady=10,anchor='w')self.var_phone = tk.Entry(self.window, width=40, font=tkFont.Font(size=20), bg='Ivory')self.var_phone.pack(anchor='nw')Button(self.window, text="注册", width=20, font=tkFont.Font(size=15), command=self.new_row).pack(pady=20)Button(self.window, text="返回首页", width=20, font=tkFont.Font(size=15), command=self.back).pack(pady=20)self.window.protocol("WM_DELETE_WINDOW", self.back) # 捕捉右上角关闭点击self.window.mainloop() # 进入消息循环def new_row(self):#从界面获取的数据print(self.var_userid.get())print(self.admin_userid)if str(self.var_userid.get()) in self.admin_userid:messagebox.showinfo('警告!', '该用户已存在!')elif (len(str(self.var_phone.get())) > 15) or (len(str(self.var_phone.get())) < 7):messagebox.showinfo('警告!', '请输入正确的电话号码!')else:if self.var_userid.get() != '' and self.var_pass.get() != '' and self.var_name.get() != '' and self.var_sex.get() != '' and self.var_phone.get() != '':# 打开数据库连接con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标sql = "INSERT INTO 游客信息(游客账号,游客密码,游客姓名,游客性别,联系电话) \VALUES ('%s', '%s', '%s', '%s', '%s')" % \(self.var_userid.get(), self.var_pass.get(),self.var_name.get(), self.var_sex.get(),self.var_phone.get()) # SQL 插入语句try:cursor.execute(sql) # 执行sql语句con.commit() # 提交到数据库执行except:con.rollback() # 发生错误时回滚messagebox.showinfo('警告!', '数据库连接失败!')con.close() # 关闭数据库连接self.admin_userid.append(self.var_userid.get())self.admin_pass.append(self.var_pass.get())self.admin_name.append(self.var_name.get())self.admin_sex.append(self.var_sex.get())self.admin_phone.append(self.var_phone.get())messagebox.showinfo('提示!', '注册成功!')else:messagebox.showinfo('警告!', '请填写正确的信息')def back(self):StartPage(self.window) # 显示主窗口 销毁本窗口#游客端页面
class TourKit:def __init__(self, parent_window):parent_window.destroy() # 销毁主界面self.window = tk.Tk() # 初始框的声明self.window.title('首页')self.window.geometry('900x900') # 这里的乘是小xself.window.geometry('+330+0')self.ticketid = [] #订票编号self.identityid = [] #游客账号self.phone = [] #身份证号self.num = [] #联系电话self.money = [] #订票数量#self.time = [] #应付金额#self.timee = [] #订票时间self.var_ticketid = StringVar() # 声明订票编号self.var_identityid= StringVar() # 声明游客账号self.var_idid = StringVar() # 声明身份证号self.var_phonee = StringVar() #声明联系电话self.var_num = StringVar() # 声明订票数量#self.var_time = StringVar() # 声明应付金额#self.var_timee = StringVar() # 声明订票时间label = tk.Label(self.window, text='操作页面', bg='green', font=('Verdana', 30), width=40, height=3)label.pack()Label(self.window, text='订票编号:', font=tkFont.Font(size=15)).pack(pady=10,anchor='w')self.var_ticketid = tk.Entry(self.window, width=40, font=tkFont.Font(size=20), bg='Ivory')self.var_ticketid.pack(anchor='nw')Label(self.window, text='账号:', font=tkFont.Font(size=15)).pack(pady=10,anchor='w')self.var_identityid = tk.Entry(self.window, width=40, font=tkFont.Font(size=20), bg='Ivory')self.var_identityid.pack(anchor='nw')Label(self.window, text='身份证号:', font=tkFont.Font(size=15)).pack(pady=10,anchor='w')self.var_idid = tk.Entry(self.window, width=40, font=tkFont.Font(size=20), bg='Ivory')self.var_idid.pack(anchor='nw')Label(self.window, text='联系电话:', font=tkFont.Font(size=15)).pack(pady=10,anchor='w')self.var_phonee = tk.Entry(self.window, width=40, font=tkFont.Font(size=20), bg='Ivory')self.var_phonee.pack(anchor='nw')Label(self.window, text='订票数量:', font=tkFont.Font(size=15)).pack(pady=10,anchor='w')self.var_num = tk.Entry(self.window, width=40, font=tkFont.Font(size=20), bg='Ivory')self.var_num.pack(anchor='nw')Button(self.window, text="订票", width=10, font=tkFont.Font(size=15), command=self.new_row).pack(pady=40)Button(self.window, text="退票", width=10, font=tkFont.Font(size=15), command=self.del_row).pack(pady=40)Button(self.window, text="退出登录", width=10, font=tkFont.Font(size=15), command=self.back).pack()# 打开数据库连接con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标#sql = "SELECT * FROM 游客信息 WHERE 游客账号 = '%s'" % (self.var_identityid.get()) # SQL 查询语句sql = "SELECT * FROM 游客信息"try:# 执行SQL语句cursor.execute(sql)# 获取所有记录列表results = cursor.fetchall()for row in results:self.identityid.append(row[0])#self.ticketid.append(row[1])#self.phone.append(row[2])#self.money.append(row[3])#self.time.append(row[4])#self.timee.append(row[5])except:print("Error: unable to fetch data")messagebox.showinfo('警告!', '数据库连接失败!')con.close()# 关闭数据库连接# 打开数据库连接con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标#sql = "SELECT * FROM 游客信息 WHERE 游客账号 = '%s'" % (self.var_identityid.get()) # SQL 查询语句sql = "SELECT * FROM 订票信息"try:# 执行SQL语句cursor.execute(sql)# 获取所有记录列表results = cursor.fetchall()for i in results:#self.identityid.append(row[0])self.ticketid.append(i[0])#self.phone.append(row[2])#self.money.append(row[3])#self.time.append(row[4])#self.timee.append(row[5])except:print("Error: unable to fetch data")messagebox.showinfo('警告!', '数据库连接失败!')con.close()# 关闭数据库连接self.window.protocol("WM_DELETE_WINDOW", self.back) # 捕捉右上角关闭点击self.window.mainloop() # 进入消息循环def new_row(self):#从界面获取的数据print(self.var_identityid.get())print(self.identityid)print(self.ticketid)if str(self.var_identityid.get()) not in self.identityid:messagebox.showinfo('警告!', '请输入正确的账号!')elif len(str(self.var_idid.get())) != 18 :messagebox.showinfo('警告!', '请输入正确的身份证号')elif (len(str(self.var_phonee.get())) > 15) or (len(str(self.var_phonee.get())) < 7):messagebox.showinfo('警告!', '请输入正确的电话号码!')else:if self.var_identityid.get() != '' and self.var_idid.get() != '' and self.var_phonee.get() != '' and self.var_num.get() != '':# 打开数据库连接con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标sql = "INSERT INTO 订票信息(游客账号,身份证号,联系电话,订票数量) \VALUES ('%s', '%s', '%s', '%s')" % \(self.var_identityid.get(), self.var_idid.get(), self.var_phonee.get(), self.var_num.get()) # SQL 插入语句try:cursor.execute(sql) # 执行sql语句con.commit() # 提交到数据库执行except:con.rollback() # 发生错误时回滚messagebox.showinfo('警告!', '数据库连接失败!')con.close() # 关闭数据库连接#self.ticketid.append()self.identityid.append(self.var_identityid.get())self.phone.append(self.var_idid.get())self.num.append(self.var_phonee.get())self.money.append(self.var_num.get())messagebox.showinfo('提示!', '订票成功!')else:messagebox.showinfo('警告!', '请填写正确的信息')def del_row(self):#从界面获取的数据print(self.var_identityid.get())print(self.identityid)print(self.var_ticketid.get())print(self.ticketid)if str(self.var_identityid.get()) not in self.identityid:messagebox.showinfo('警告!', '请输入正确的账号!')else:if str(self.var_ticketid.get()) in str(self.ticketid):# 打开数据库连接con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标sql = "DELETE FROM 订票信息 WHERE 订票编号 = '%s'" % (self.var_ticketid.get()) # SQL 插入语句try:cursor.execute(sql) # 执行sql语句con.commit() # 提交到数据库执行except:con.rollback() # 发生错误时回滚messagebox.showinfo('警告!', '数据库连接失败!')con.close() # 关闭数据库连接#self.identityid.remove(self.var_identityid.get())#self.phone.remove(self.var_idid.get())#self.num.remove(self.var_phonee.get())#self.money.remove(self.var_num.get()) messagebox.showinfo('提示!', '退票成功!')else:messagebox.showinfo('警告!', '请填写正确的信息')def back(self):StartPage(self.window) # 显示主窗口 销毁本窗口# 管理员首页
class TicketMessage:def __init__(self, parent_window):parent_window.update()parent_window.destroy() # 销毁子界面self.window = tk.Tk() # 初始框的声明self.window.title('首页')self.window.geometry('900x900') # 这里的乘是小xself.window.geometry('+330+0')label = Label(self.window, text="门票相关信息", font=("Verdana", 20))label.pack(pady=100) # pady=100 界面的长度Button(self.window, text="订票信息", font=tkFont.Font(size=16), command=lambda: BuyTicket(self.window), width=30, height=2,fg='white', bg='gray', activebackground='black', activeforeground='white').pack()Button(self.window, text="退票信息", font=tkFont.Font(size=16), command=lambda: RefundTicket(self.window), width=30,height=2,fg='white', bg='gray', activebackground='black', activeforeground='white').pack()Button(self.window, text="游客信息", font=tkFont.Font(size=16), command=lambda: YoKe(self.window), width=30,height=2,fg='white', bg='gray', activebackground='black', activeforeground='white').pack()Button(self.window, text="退出登录", font=tkFont.Font(size=16), command=lambda: StartPage(self.window), width=30,height=2,fg='white', bg='gray', activebackground='black', activeforeground='white').pack()self.window.mainloop() # 主消息循环 # 管理员操作订票信息
class BuyTicket:def __init__(self, parent_window):parent_window.destroy() # 自动销毁上一个界面self.window = Tk() # 初始框的声明self.window.title('管理员操作界面')self.window.geometry("900x900+300+0") # 初始窗口在屏幕中的位置self.frame_left_top = tk.Frame(width=300, height=300) # 指定框架,在窗口上可以显示,这里指定四个框架 self.frame_right_top = tk.Frame(width=300, height=300)self.frame_center = tk.Frame(width=900, height=400)self.frame_bottom = tk.Frame(width=650, height=70)# 定义下方中心列表区域self.columns = ("订票编号", "游客账号", "身份证号", "联系电话", "订票数量", "应付金额" , "订票时间")self.tree = ttk.Treeview(self.frame_center, show="headings", height=30, columns=self.columns)# 添加竖直滚动条self.vbar = ttk.Scrollbar(self.frame_center, orient=VERTICAL, command=self.tree.yview)# 定义树形结构与滚动条self.tree.configure(yscrollcommand=self.vbar.set)# 定义id1为修改id时的暂存变量,这个是为了更新信息而设计的self.id1 = 0# 表格的标题self.tree.column("订票编号", width=120, anchor='center') # 表示列,不显示self.tree.column("游客账号", width=120, anchor='center')self.tree.column("身份证号", width=120, anchor='center')self.tree.column("联系电话", width=120, anchor='center')self.tree.column("订票数量", width=120, anchor='center')self.tree.column("应付金额", width=120, anchor='center')self.tree.column("订票时间", width=150, anchor='center')# grid方法将tree和vbar进行布局self.tree.grid(row=0, column=0, sticky=NSEW)self.vbar.grid(row=0, column=1, sticky=NS)# 定义几个数组,为中间的那个大表格做一些准备#self.id = []#self.name = []#self.gender = []#self.age = []self.ticketid = [] #订票编号self.identityid = [] #游客账号self.idid = [] #身份证号self.phonee = [] #联系电话self.numm = [] #订票数量self.mm = [] #应付金额self.timee = [] #订票时间# 打开数据库连接con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标sql = "SELECT * FROM 订票信息"try:# 执行SQL语句cursor.execute(sql)# 获取所有记录列表results = cursor.fetchall()for row in results:#self.id.append(row[0])#self.name.append(row[1])#self.gender.append(row[2])#self.age.append(row[3])self.ticketid.append(row[0])self.identityid.append(row[1])self.idid.append(row[2])self.phonee.append(row[3])self.numm.append(row[4])self.mm.append(row[5])self.timee.append(row[6])except:messagebox.showinfo('警告!', '数据库连接失败!')con.close()# 关闭数据库连接print("test***********************")for i in range(min(len(self.ticketid),len(self.identityid), len(self.idid), len(self.phonee), len(self.numm),len(self.mm),len(self.timee))): # 写入数据self.tree.insert('', i, values=(self.ticketid[i], self.identityid[i], self.idid[i], self.phonee[i], self.numm[i], self.mm[i], self.timee[i]))for col in self.columns: # 绑定函数,使表头可排序self.tree.heading(col, text=col,command=lambda _col=col: self.tree_sort_column(self.tree, _col, False))# 定义下方区域self.chaxun = StringVar()self.right_bottom_gender_entry = Entry(self.frame_bottom, textvariable=self.chaxun, font=('Verdana', 15))self.right_bottom_button = ttk.Button(self.frame_bottom, text='游客门票查询', width=20, command=self.put_data)self.right_bottom_button.grid(row=0, column=0, padx=20, pady=20) # 位置设置self.right_bottom_gender_entry.grid(row=0, column=1)self.left_top_frame = tk.Frame(self.frame_left_top)self.var_ticketid = StringVar() # 声明订票编号self.var_identityid= StringVar() # 声明游客账号self.var_idid = StringVar() # 声明身份证号self.var_phonee = StringVar() # 声明联系电话self.var_numm = StringVar() # 声明订票数量self.var_mm = StringVar() # 声明应付金额self.var_timee = StringVar() # 声明订票时间# 定义顶部区域# 定义左上方区域self.top_title = Label(self.frame_left_top, text="门票信息:", font=('Verdana', 20))self.top_title.grid(row=0, column=0, columnspan=2, sticky=NSEW, padx=50, pady=10) # NSEW表示允许组件向4个方向都可以拉伸# 订票编号self.right_top_id_label = Label(self.frame_left_top, text="订票编号:", font=('Verdana', 15))self.right_top_id_entry = Entry(self.frame_left_top, textvariable=self.var_ticketid, font=('Verdana', 15))self.right_top_id_label.grid(row=1, column=0) # 位置设置self.right_top_id_entry.grid(row=1, column=1)# 游客账号self.right_top_id_label = Label(self.frame_left_top, text="游客账号:", font=('Verdana', 15))self.right_top_id_entry = Entry(self.frame_left_top, textvariable=self.var_identityid, font=('Verdana', 15))self.right_top_id_label.grid(row=2, column=0) # 位置设置self.right_top_id_entry.grid(row=2, column=1)# 身份证号self.right_top_name_label = Label(self.frame_left_top, text="身份证号:", font=('Verdana', 15))self.right_top_name_entry = Entry(self.frame_left_top, textvariable=self.var_idid, font=('Verdana', 15))self.right_top_name_label.grid(row=3, column=0) # 位置设置self.right_top_name_entry.grid(row=3, column=1)# 联系电话self.right_top_name_label = Label(self.frame_left_top, text="联系电话:", font=('Verdana', 15))self.right_top_name_entry = Entry(self.frame_left_top, textvariable=self.var_phonee, font=('Verdana', 15))self.right_top_name_label.grid(row=4, column=0) # 位置设置self.right_top_name_entry.grid(row=4, column=1)# 订票数量self.right_top_gender_label = Label(self.frame_left_top, text="订票数量:", font=('Verdana', 15))self.right_top_gender_entry = Entry(self.frame_left_top, textvariable=self.var_numm,font=('Verdana', 15))self.right_top_gender_label.grid(row=5, column=0) # 位置设置self.right_top_gender_entry.grid(row=5, column=1)# 应付金额self.right_top_gender_label = Label(self.frame_left_top, text="应付金额:", font=('Verdana', 15))self.right_top_gender_entry = Entry(self.frame_left_top, textvariable=self.var_mm,font=('Verdana', 15))self.right_top_gender_label.grid(row=6, column=0) # 位置设置self.right_top_gender_entry.grid(row=6, column=1)# 订票时间self.right_top_gender_label = Label(self.frame_left_top, text="订票时间:", font=('Verdana', 15))self.right_top_gender_entry = Entry(self.frame_left_top, textvariable=self.var_timee,font=('Verdana', 15))self.right_top_gender_label.grid(row=7, column=0) # 位置设置self.right_top_gender_entry.grid(row=7, column=1)# 定义右上方区域self.right_top_title = Label(self.frame_right_top, text="操作:", font=('Verdana', 20))self.tree.bind('<Button-1>', self.click) # 左键获取位置(tree.bind可以绑定一系列的事件,可以搜索ttk相关参数查看)self.right_top_button1 = ttk.Button(self.frame_right_top, text='订票', width=20, command=self.new_row)self.right_top_button2 = ttk.Button(self.frame_right_top, text='更新游客信息', width=20,command=self.updata_row)self.right_top_button3 = ttk.Button(self.frame_right_top, text='退票', width=20,command=self.del_row)self.right_top_button4 = ttk.Button(self.frame_right_top, text='返回', width=20,command=self.back)# 定义下方区域,查询功能块self.chaxun = StringVar()self.right_bottom_gender_entry = Entry(self.frame_bottom, textvariable=self.chaxun, font=('Verdana', 15))self.right_bottom_button = ttk.Button(self.frame_bottom, text='游客门票查询', width=20, command=self.put_data)self.right_bottom_button.grid(row=0, column=0, padx=20, pady=20) # 位置设置self.right_bottom_gender_entry.grid(row=0, column=1)# 右上角按钮的位置设置self.right_top_title.grid(row=1, column=0, pady=10)self.right_top_button1.grid(row=2, column=0, padx=20, pady=10)self.right_top_button2.grid(row=3, column=0, padx=20, pady=10)self.right_top_button3.grid(row=4, column=0, padx=20, pady=10)self.right_top_button4.grid(row=5, column=0, padx=20, pady=10)# 整体区域定位,利用了Frame和grid进行布局self.frame_left_top.grid(row=0, column=0, padx=2, pady=5)self.frame_right_top.grid(row=0, column=1, padx=30, pady=30)self.frame_center.grid(row=1, column=0, columnspan=2, padx=4, pady=5)self.frame_bottom.grid(row=2, column=0, columnspan=2)# 设置固定组件,(0)就是将组件进行了固定self.frame_left_top.grid_propagate(0)self.frame_right_top.grid_propagate(0)self.frame_center.grid_propagate(0)self.frame_bottom.grid_propagate(0)self.frame_left_top.tkraise() # 开始显示主菜单,tkraise()提高z轴的顺序(不太懂)self.frame_right_top.tkraise() # 开始显示主菜单self.frame_center.tkraise() # 开始显示主菜单self.frame_bottom.tkraise() # 开始显示主菜单self.window.protocol("WM_DELETE_WINDOW", self.back) # 捕捉右上角关闭点击,执行back方法self.window.mainloop() # 进入消息循环# 将查到的信息放到中间的表格中def put_data(self):self.delButton() # 先将表格内的内容全部清空# print(self.chaxun.get()) # 输入框内的内容 # 打开数据库连接,准备查找指定的信息con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标#sql = "use EMIS exec proc_cha '%s'" % (self.chaxun.get())sql = "SELECT * FROM 订票信息 WHERE 游客账号 = '%s' " % (self.chaxun.get())try:# 执行SQL语句cursor.execute(sql)# 获取所有记录列表results = cursor.fetchall()# 再次进行初始化,进行首行数据的插入self.ticketid = [] #订票编号self.identityid = [] #游客账号self.idid = [] #身份证号self.phonee = [] #联系电话self.numm = [] #订票数量self.mm = [] #应付金额self.timee = [] #订票时间for row in results:self.ticketid.append(row[0])self.identityid.append(row[1])self.idid.append(row[2])self.phonee.append(row[3])self.numm.append(row[4])self.mm.append(row[5])self.timee.append(row[6])except:print("Error: unable to fetch data")messagebox.showinfo('警告!', '数据库连接失败!')con.close()# 关闭数据库连接print("进行数据的插入")for i in range(min(len(self.ticketid),len(self.identityid), len(self.idid), len(self.phonee), len(self.numm),len(self.mm),len(self.timee))): # 写入数据self.tree.insert('', i, values=(self.ticketid[i], self.identityid[i], self.idid[i], self.phonee[i], self.numm[i], self.mm[i], self.timee[i]))for col in self.columns: # 绑定函数,使表头可排序self.tree.heading(col, text=col,command=lambda _col=col: self.tree_sort_column(self.tree, _col, False))# 清空表格中的所有信息def delButton(self):x=self.tree.get_children()for item in x:self.tree.delete(item)# 在表格上的点击事件,这里是作用就是一点击表格就可以将信息直接写到左上角的框框中def click(self, event):self.col = self.tree.identify_column(event.x) # 通过tree.identify_column()函数可以直接获取到列self.row = self.tree.identify_row(event.y) # 行print(self.col)print(self.row)self.row_info = self.tree.item(self.row, "values")self.var_ticketid.set(self.row_info[0])self.id1 = self.var_ticketid.get()self.var_identityid.set(self.row_info[1])self.var_idid.set(self.row_info[2])self.var_phonee.set(self.row_info[3])self.var_numm.set(self.row_info[4])self.var_mm.set(self.row_info[5])self.var_timee.set(self.row_info[6])self.right_top_id_entry = Entry(self.frame_left_top, state='disabled', textvariable=self.var_ticketid, font=('Verdana', 15))# 点击中间的表格的表头,可以将那一列进行排序def tree_sort_column(self, tv, col, reverse): # Treeview、列名、排列方式l = [(tv.set(k, col), k) for k in tv.get_children('')]l.sort(reverse=reverse) # 排序方式for index, (val, k) in enumerate(l): # 根据排序后索引移动tv.move(k, '', index)tv.heading(col, command=lambda: self.tree_sort_column(tv, col, not reverse)) # 重写标题,使之成为再点倒序的标题#更新信息 def new_row(self):self.delButton() # 先将表格内的内容全部清空print('123')#print(self.var_ticketid.get())#print(self.ticketid)if self.var_identityid.get() not in self.identityid:messagebox.showinfo('警告!', '请输入您的账号!')elif len(str(self.var_idid.get())) != 18:messagebox.showinfo('警告!', '请输入正确的身份证号!')elif (len(str(self.var_phonee.get())) > 15) or (len(str(self.var_phonee.get())) < 7):messagebox.showinfo('警告!', '请输入正确的电话号码!')else:if self.var_identityid.get() != '' and self.var_idid.get() != '' and self.var_phonee.get() != '' and self.var_numm.get() != '':# 打开数据库连接con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标sql = "INSERT INTO 订票信息(游客账号,身份证号,联系电话,订票数量) \VALUES ('%s', '%s', '%s', '%s')" % \(self.var_identityid.get(), self.var_idid.get(), self.var_phonee.get(),self.var_numm.get()) # SQL 插入语句try:cursor.execute(sql) # 执行sql语句con.commit() # 提交到数据库执行except:con.rollback() # 发生错误时回滚messagebox.showinfo('警告!', '数据库连接失败!')con.close() # 关闭数据库连接# 向表格中插入数据con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标#sql = "use EMIS exec proc_cha '%s'" % (self.chaxun.get())sql = "SELECT * FROM 订票信息" try:# 执行SQL语句cursor.execute(sql)# 获取所有记录列表results = cursor.fetchall()# 再次进行初始化,进行首行数据的插入self.ticketid = [] #订票编号self.identityid = [] #游客账号self.idid = [] #身份证号self.phonee = [] #联系电话self.numm = [] #订票数量self.mm = [] #应付金额self.timee = [] #订票时间for row in results:self.ticketid.append(row[0])self.identityid.append(row[1])self.idid.append(row[2])self.phonee.append(row[3])self.numm.append(row[4])self.mm.append(row[5])self.timee.append(row[6])except:print("Error: unable to fetch data")messagebox.showinfo('警告!', '数据库连接失败!')con.close()# 关闭数据库连接print("进行数据的插入")for i in range(min(len(self.ticketid),len(self.identityid), len(self.idid), len(self.phonee), len(self.numm),len(self.mm),len(self.timee))): # 写入数据self.tree.insert('', i, values=(self.ticketid[i], self.identityid[i], self.idid[i], self.phonee[i], self.numm[i], self.mm[i], self.timee[i]))for col in self.columns: # 绑定函数,使表头可排序self.tree.heading(col, text=col,command=lambda _col=col: self.tree_sort_column(self.tree, _col, False))self.tree.update() messagebox.showinfo('提示!', '订票成功!')else:messagebox.showinfo('警告!', '请填写正确信息')def updata_row(self):self.delButton() # 先将表格内的内容全部清空res = messagebox.askyesnocancel('警告!', '是否更新所填数据?')if res == True:if self.var_ticketid.get() == self.row_info[0] and self.var_identityid.get() ==self.row_info[1]: # 如果所填学号 与 所选学号一致# 打开数据库连接con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标sql = "UPDATE 订票信息 SET 身份证号 = '%s', 联系电话 = '%s', 订票数量 = '%s' \WHERE 订票编号 = '%s'" % (self.var_idid.get(), self.var_phonee.get(), self.var_numm.get(), self.var_ticketid.get()) # SQL 插入语句if len(str(self.var_idid.get())) != 18:messagebox.showinfo('警告!', '请输入正确的身份证号!')elif (len(str(self.var_phonee.get())) > 15) or (len(str(self.var_phonee.get())) < 7):messagebox.showinfo('警告!', '请输入正确的电话号码!')else:try:cursor.execute(sql) # 执行sql语句con.commit() # 提交到数据库执行messagebox.showinfo('提示!', '更新成功!')except:con.rollback() # 发生错误时回滚messagebox.showinfo('警告!', '更新失败,数据库连接失败!')con.close() # 关闭数据库连# 向表格中插入数据con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标#sql = "use EMIS exec proc_cha '%s'" % (self.chaxun.get())sql = "SELECT * FROM 订票信息" try:# 执行SQL语句cursor.execute(sql)# 获取所有记录列表results = cursor.fetchall()# 再次进行初始化,进行首行数据的插入self.ticketid = [] #订票编号self.identityid = [] #游客账号self.idid = [] #身份证号self.phonee = [] #联系电话self.numm = [] #订票数量self.mm = [] #应付金额self.timee = [] #订票时间for row in results:self.ticketid.append(row[0])self.identityid.append(row[1])self.idid.append(row[2])self.phonee.append(row[3])self.numm.append(row[4])self.mm.append(row[5])self.timee.append(row[6])except:print("Error: unable to fetch data")messagebox.showinfo('警告!', '数据库连接失败!')con.close()# 关闭数据库连接print("进行数据的插入")for i in range(min(len(self.ticketid),len(self.identityid), len(self.idid), len(self.phonee), len(self.numm),len(self.mm),len(self.timee))): # 写入数据self.tree.insert('', i, values=(self.ticketid[i], self.identityid[i], self.idid[i], self.phonee[i], self.numm[i], self.mm[i], self.timee[i]))for col in self.columns: # 绑定函数,使表头可排序self.tree.heading(col, text=col,command=lambda _col=col: self.tree_sort_column(self.tree, _col, False)) #messagebox.showinfo('提示!', '更新失败!')self.tree.update() else:messagebox.showinfo('提示!', '请填写正确的信息!')# 删除行def del_row(self):#self.delButton() # 先将表格内的内容全部清空res = messagebox.askyesnocancel('警告!', '是否删除所选数据?')if res == True:print(self.row_info[0]) # 鼠标选中的学号print(self.tree.selection()[0]) # 行号print(self.tree.get_children()) # 所有行# 打开数据库连接con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8') cursor = con.cursor() # 使用cursor()方法获取操作游标#sql = "use EMIS exec proc_delete '%s'" % (self.row_info[0]) # SQL 插入语句sql = "DELETE FROM 订票信息 WHERE 订票编号 = '%s'" % (self.row_info[0]) # SQL 插入语句try:cursor.execute(sql) # 执行sql语句con.commit() # 提交到数据库执行messagebox.showinfo('提示!', '退票成功!')except:con.rollback() # 发生错误时回滚messagebox.showinfo('警告!', '删除失败,数据库连接失败!')con.close() # 关闭数据库连接id_index = self.ticketid.index(self.row_info[0])print(id_index)del self.ticketid[id_index]del self.identityid[id_index]del self.idid[id_index]del self.phonee[id_index]del self.numm[id_index]del self.mm[id_index]#del self.timee[id_index]print(self.ticketid)self.tree.delete(self.tree.selection()[0]) # 删除所选行print(self.tree.get_children())self.tree.update()def back(self):TicketMessage(self.window) # 进入管理员操作界面 # 退票信息
# 管理员操作退票信息
class RefundTicket:def __init__(self, parent_window):parent_window.destroy() # 自动销毁上一个界面self.window = Tk() # 初始框的声明self.window.title('退票信息界面')self.window.geometry("900x900+300+0") # 初始窗口在屏幕中的位置self.frame_left_top = tk.Frame(width=300, height=300) # 指定框架,在窗口上可以显示,这里指定四个框架 self.frame_right_top = tk.Frame(width=300, height=300)self.frame_center = tk.Frame(width=900, height=400)self.frame_bottom = tk.Frame(width=650, height=70)# 定义下方中心列表区域self.columns = ("订票编号", "游客账号", "身份证号", "联系电话", "退票数量", "退还金额" , "退票时间")self.tree = ttk.Treeview(self.frame_center, show="headings", height=30, columns=self.columns)# 添加竖直滚动条self.vbar = ttk.Scrollbar(self.frame_center, orient=VERTICAL, command=self.tree.yview)# 定义树形结构与滚动条self.tree.configure(yscrollcommand=self.vbar.set)# 定义id1为修改id时的暂存变量,这个是为了更新信息而设计的self.id1 = 0# 表格的标题self.tree.column("订票编号", width=120, anchor='center') # 表示列,不显示self.tree.column("游客账号", width=120, anchor='center')self.tree.column("身份证号", width=120, anchor='center')self.tree.column("联系电话", width=120, anchor='center')self.tree.column("退票数量", width=120, anchor='center')self.tree.column("退还金额", width=120, anchor='center')self.tree.column("退票时间", width=150, anchor='center')# grid方法将tree和vbar进行布局self.tree.grid(row=0, column=0, sticky=NSEW)self.vbar.grid(row=0, column=1, sticky=NS)# 定义几个数组,为中间的那个大表格做一些准备#self.id = []#self.name = []#self.gender = []#self.age = []self.ticketid = [] #订票编号self.identityid = [] #游客账号self.idid = [] #身份证号self.phonee = [] #联系电话self.numm = [] #订票数量self.mm = [] #应付金额self.timee = [] #订票时间# 打开数据库连接con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标sql = "SELECT * FROM 退票信息"try:# 执行SQL语句cursor.execute(sql)# 获取所有记录列表results = cursor.fetchall()for row in results:#self.id.append(row[0])#self.name.append(row[1])#self.gender.append(row[2])#self.age.append(row[3])self.ticketid.append(row[0])self.identityid.append(row[1])self.idid.append(row[2])self.phonee.append(row[3])self.numm.append(row[4])self.mm.append(row[5])self.timee.append(row[6])except:messagebox.showinfo('警告!', '数据库连接失败!')con.close()# 关闭数据库连接print("test***********************")for i in range(min(len(self.ticketid),len(self.identityid), len(self.idid), len(self.phonee), len(self.numm),len(self.mm),len(self.timee))): # 写入数据self.tree.insert('', i, values=(self.ticketid[i], self.identityid[i], self.idid[i], self.phonee[i], self.numm[i], self.mm[i], self.timee[i]))for col in self.columns: # 绑定函数,使表头可排序self.tree.heading(col, text=col,command=lambda _col=col: self.tree_sort_column(self.tree, _col, False))# 定义下方区域self.chaxun = StringVar()self.right_bottom_gender_entry = Entry(self.frame_bottom, textvariable=self.chaxun, font=('Verdana', 15))self.right_bottom_button = ttk.Button(self.frame_bottom, text='游客退票查询', width=20, command=self.put_data)self.right_bottom_button.grid(row=0, column=0, padx=20, pady=20) # 位置设置self.right_bottom_gender_entry.grid(row=0, column=1)self.left_top_frame = tk.Frame(self.frame_left_top)self.var_ticketid = StringVar() # 声明订票编号self.var_identityid= StringVar() # 声明游客账号self.var_idid = StringVar() # 声明身份证号self.var_phonee = StringVar() # 声明联系电话self.var_numm = StringVar() # 声明订票数量self.var_mm = StringVar() # 声明应付金额self.var_timee = StringVar() # 声明订票时间# 定义顶部区域# 定义左上方区域self.top_title = Label(self.frame_left_top, text="门票信息:", font=('Verdana', 20))self.top_title.grid(row=0, column=0, columnspan=2, sticky=NSEW, padx=50, pady=10) # NSEW表示允许组件向4个方向都可以拉伸# 订票编号self.right_top_id_label = Label(self.frame_left_top, text="订票编号:", font=('Verdana', 15))self.right_top_id_entry = Entry(self.frame_left_top, textvariable=self.var_ticketid, font=('Verdana', 15))self.right_top_id_label.grid(row=1, column=0) # 位置设置self.right_top_id_entry.grid(row=1, column=1)# 游客账号self.right_top_id_label = Label(self.frame_left_top, text="游客账号:", font=('Verdana', 15))self.right_top_id_entry = Entry(self.frame_left_top, textvariable=self.var_identityid, font=('Verdana', 15))self.right_top_id_label.grid(row=2, column=0) # 位置设置self.right_top_id_entry.grid(row=2, column=1)# 身份证号self.right_top_name_label = Label(self.frame_left_top, text="身份证号:", font=('Verdana', 15))self.right_top_name_entry = Entry(self.frame_left_top, textvariable=self.var_idid, font=('Verdana', 15))self.right_top_name_label.grid(row=3, column=0) # 位置设置self.right_top_name_entry.grid(row=3, column=1)# 联系电话self.right_top_name_label = Label(self.frame_left_top, text="联系电话:", font=('Verdana', 15))self.right_top_name_entry = Entry(self.frame_left_top, textvariable=self.var_phonee, font=('Verdana', 15))self.right_top_name_label.grid(row=4, column=0) # 位置设置self.right_top_name_entry.grid(row=4, column=1)# 订票数量self.right_top_gender_label = Label(self.frame_left_top, text="退票数量:", font=('Verdana', 15))self.right_top_gender_entry = Entry(self.frame_left_top, textvariable=self.var_numm,font=('Verdana', 15))self.right_top_gender_label.grid(row=5, column=0) # 位置设置self.right_top_gender_entry.grid(row=5, column=1)# 应付金额self.right_top_gender_label = Label(self.frame_left_top, text="退还金额:", font=('Verdana', 15))self.right_top_gender_entry = Entry(self.frame_left_top, textvariable=self.var_mm,font=('Verdana', 15))self.right_top_gender_label.grid(row=6, column=0) # 位置设置self.right_top_gender_entry.grid(row=6, column=1)# 订票时间self.right_top_gender_label = Label(self.frame_left_top, text="退票时间:", font=('Verdana', 15))self.right_top_gender_entry = Entry(self.frame_left_top, textvariable=self.var_timee,font=('Verdana', 15))self.right_top_gender_label.grid(row=7, column=0) # 位置设置self.right_top_gender_entry.grid(row=7, column=1)# 定义右上方区域self.right_top_title = Label(self.frame_right_top, text="操作:", font=('Verdana', 20))self.tree.bind('<Button-1>', self.click) # 左键获取位置(tree.bind可以绑定一系列的事件,可以搜索ttk相关参数查看)#self.right_top_button1 = ttk.Button(self.frame_right_top, text='订票', width=20, command=self.new_row)#self.right_top_button2 = ttk.Button(self.frame_right_top, text='更新游客信息', width=20,command=self.updata_row)self.right_top_button3 = ttk.Button(self.frame_right_top, text='删除', width=20,command=self.del_row)self.right_top_button4 = ttk.Button(self.frame_right_top, text='返回', width=20,command=self.back)# 定义下方区域,查询功能块self.chaxun = StringVar()self.right_bottom_gender_entry = Entry(self.frame_bottom, textvariable=self.chaxun, font=('Verdana', 15))self.right_bottom_button = ttk.Button(self.frame_bottom, text='游客门票查询', width=20, command=self.put_data)self.right_bottom_button.grid(row=0, column=0, padx=20, pady=20) # 位置设置self.right_bottom_gender_entry.grid(row=0, column=1)# 右上角按钮的位置设置self.right_top_title.grid(row=1, column=0, pady=10)#self.right_top_button1.grid(row=2, column=0, padx=20, pady=10)#self.right_top_button2.grid(row=3, column=0, padx=20, pady=10)self.right_top_button3.grid(row=4, column=0, padx=20, pady=10)self.right_top_button4.grid(row=5, column=0, padx=20, pady=10)# 整体区域定位,利用了Frame和grid进行布局self.frame_left_top.grid(row=0, column=0, padx=2, pady=5)self.frame_right_top.grid(row=0, column=1, padx=30, pady=30)self.frame_center.grid(row=1, column=0, columnspan=2, padx=4, pady=5)self.frame_bottom.grid(row=2, column=0, columnspan=2)# 设置固定组件,(0)就是将组件进行了固定self.frame_left_top.grid_propagate(0)self.frame_right_top.grid_propagate(0)self.frame_center.grid_propagate(0)self.frame_bottom.grid_propagate(0)self.frame_left_top.tkraise() # 开始显示主菜单,tkraise()提高z轴的顺序(不太懂)self.frame_right_top.tkraise() # 开始显示主菜单self.frame_center.tkraise() # 开始显示主菜单self.frame_bottom.tkraise() # 开始显示主菜单self.window.protocol("WM_DELETE_WINDOW", self.back) # 捕捉右上角关闭点击,执行back方法self.window.mainloop() # 进入消息循环# 将查到的信息放到中间的表格中def put_data(self):self.delButton() # 先将表格内的内容全部清空# print(self.chaxun.get()) # 输入框内的内容 # 打开数据库连接,准备查找指定的信息con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标#sql = "use EMIS exec proc_cha '%s'" % (self.chaxun.get())sql = "SELECT * FROM 退票信息 WHERE 游客账号 = '%s' " % (self.chaxun.get())try:# 执行SQL语句cursor.execute(sql)# 获取所有记录列表results = cursor.fetchall()# 再次进行初始化,进行首行数据的插入self.ticketid = [] #订票编号self.identityid = [] #游客账号self.idid = [] #身份证号self.phonee = [] #联系电话self.numm = [] #订票数量self.mm = [] #应付金额self.timee = [] #订票时间for row in results:self.ticketid.append(row[0])self.identityid.append(row[1])self.idid.append(row[2])self.phonee.append(row[3])self.numm.append(row[4])self.mm.append(row[5])self.timee.append(row[6])except:print("Error: unable to fetch data")messagebox.showinfo('警告!', '数据库连接失败!')con.close()# 关闭数据库连接print("进行数据的插入")for i in range(min(len(self.ticketid),len(self.identityid), len(self.idid), len(self.phonee), len(self.numm),len(self.mm),len(self.timee))): # 写入数据self.tree.insert('', i, values=(self.ticketid[i], self.identityid[i], self.idid[i], self.phonee[i], self.numm[i], self.mm[i], self.timee[i]))for col in self.columns: # 绑定函数,使表头可排序self.tree.heading(col, text=col,command=lambda _col=col: self.tree_sort_column(self.tree, _col, False))# 清空表格中的所有信息def delButton(self):x=self.tree.get_children()for item in x:self.tree.delete(item)# 在表格上的点击事件,这里是作用就是一点击表格就可以将信息直接写到左上角的框框中def click(self, event):self.col = self.tree.identify_column(event.x) # 通过tree.identify_column()函数可以直接获取到列self.row = self.tree.identify_row(event.y) # 行print(self.col)print(self.row)self.row_info = self.tree.item(self.row, "values")self.var_ticketid.set(self.row_info[0])self.id1 = self.var_ticketid.get()self.var_identityid.set(self.row_info[1])self.var_idid.set(self.row_info[2])self.var_phonee.set(self.row_info[3])self.var_numm.set(self.row_info[4])self.var_mm.set(self.row_info[5])self.var_timee.set(self.row_info[6])self.right_top_id_entry = Entry(self.frame_left_top, state='disabled', textvariable=self.var_ticketid, font=('Verdana', 15))# 点击中间的表格的表头,可以将那一列进行排序def tree_sort_column(self, tv, col, reverse): # Treeview、列名、排列方式l = [(tv.set(k, col), k) for k in tv.get_children('')]l.sort(reverse=reverse) # 排序方式for index, (val, k) in enumerate(l): # 根据排序后索引移动tv.move(k, '', index)tv.heading(col, command=lambda: self.tree_sort_column(tv, col, not reverse)) # 重写标题,使之成为再点倒序的标题#更新信息,此功能暂时不用 def new_row(self):self.delButton() # 先将表格内的内容全部清空print('123')#print(self.var_ticketid.get())#print(self.ticketid)if self.var_identityid.get() not in self.identityid:messagebox.showinfo('警告!', '请输入您的账号!')else:if self.var_identityid.get() != '' and self.var_idid.get() != '' and self.var_phonee.get() != '' and self.var_numm.get() != '':# 打开数据库连接con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标sql = "INSERT INTO 退票信息(游客账号,身份证号,联系电话,退票数量) \VALUES ('%s', '%s', '%s', '%s')" % \(self.var_identityid.get(), self.var_idid.get(), self.var_phonee.get(),self.var_numm.get()) # SQL 插入语句try:cursor.execute(sql) # 执行sql语句con.commit() # 提交到数据库执行except:con.rollback() # 发生错误时回滚messagebox.showinfo('警告!', '数据库连接失败!')con.close() # 关闭数据库连接# 向表格中插入数据con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标#sql = "use EMIS exec proc_cha '%s'" % (self.chaxun.get())sql = "SELECT * FROM 退票信息" try:# 执行SQL语句cursor.execute(sql)# 获取所有记录列表results = cursor.fetchall()# 再次进行初始化,进行首行数据的插入self.ticketid = [] #订票编号self.identityid = [] #游客账号self.idid = [] #身份证号self.phonee = [] #联系电话self.numm = [] #退票数量self.mm = [] #退还金额self.timee = [] #退票时间for row in results:self.ticketid.append(row[0])self.identityid.append(row[1])self.idid.append(row[2])self.phonee.append(row[3])self.numm.append(row[4])self.mm.append(row[5])self.timee.append(row[6])except:print("Error: unable to fetch data")messagebox.showinfo('警告!', '数据库连接失败!')con.close()# 关闭数据库连接print("进行数据的插入")for i in range(min(len(self.ticketid),len(self.identityid), len(self.idid), len(self.phonee), len(self.numm),len(self.mm),len(self.timee))): # 写入数据self.tree.insert('', i, values=(self.ticketid[i], self.identityid[i], self.idid[i], self.phonee[i], self.numm[i], self.mm[i], self.timee[i]))for col in self.columns: # 绑定函数,使表头可排序self.tree.heading(col, text=col,command=lambda _col=col: self.tree_sort_column(self.tree, _col, False))self.tree.update() messagebox.showinfo('提示!', '退票成功!')else:messagebox.showinfo('警告!', '请填写正确信息')#更新数据,此功能暂时不用 def updata_row(self):self.delButton() # 先将表格内的内容全部清空res = messagebox.askyesnocancel('警告!', '是否更新所填数据?')if res == True:if self.var_ticketid.get() == self.row_info[0] and self.var_identityid.get() ==self.row_info[1]: # 如果所填学号 与 所选学号一致# 打开数据库连接con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标sql = "UPDATE 退票信息 SET 身份证号 = '%s', 联系电话 = '%s', 退票数量 = '%s' \WHERE 订票编号 = '%s'" % (self.var_idid.get(), self.var_phonee.get(), self.var_numm.get(), self.var_ticketid.get()) # SQL 插入语句try:cursor.execute(sql) # 执行sql语句con.commit() # 提交到数据库执行messagebox.showinfo('提示!', '更新成功!')except:con.rollback() # 发生错误时回滚messagebox.showinfo('警告!', '更新失败,数据库连接失败!')con.close() # 关闭数据库连# 向表格中插入数据con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标#sql = "use EMIS exec proc_cha '%s'" % (self.chaxun.get())sql = "SELECT * FROM 退票信息" try:# 执行SQL语句cursor.execute(sql)# 获取所有记录列表results = cursor.fetchall()# 再次进行初始化,进行首行数据的插入self.ticketid = [] #订票编号self.identityid = [] #游客账号self.idid = [] #身份证号self.phonee = [] #联系电话self.numm = [] #退票数量self.mm = [] #退还金额self.timee = [] #退票时间for row in results:self.ticketid.append(row[0])self.identityid.append(row[1])self.idid.append(row[2])self.phonee.append(row[3])self.numm.append(row[4])self.mm.append(row[5])self.timee.append(row[6])except:print("Error: unable to fetch data")messagebox.showinfo('警告!', '数据库连接失败!')con.close()# 关闭数据库连接print("进行数据的插入")for i in range(min(len(self.ticketid),len(self.identityid), len(self.idid), len(self.phonee), len(self.numm),len(self.mm),len(self.timee))): # 写入数据self.tree.insert('', i, values=(self.ticketid[i], self.identityid[i], self.idid[i], self.phonee[i], self.numm[i], self.mm[i], self.timee[i]))for col in self.columns: # 绑定函数,使表头可排序self.tree.heading(col, text=col,command=lambda _col=col: self.tree_sort_column(self.tree, _col, False))self.tree.update() messagebox.showinfo('提示!', '更新成功!')# 删除行def del_row(self):res = messagebox.askyesnocancel('警告!', '是否删除所选数据?')if res == True:print(self.row_info[0]) # 鼠标选中的账号print(self.tree.selection()[0]) # 行号print(self.tree.get_children()) # 所有行# 打开数据库连接con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8') cursor = con.cursor() # 使用cursor()方法获取操作游标#sql = "use EMIS exec proc_delete '%s'" % (self.row_info[0]) # SQL 插入语句sql = "DELETE FROM 退票信息 WHERE 订票编号 = '%s'" % (self.row_info[0]) # SQL 插入语句try:cursor.execute(sql) # 执行sql语句con.commit() # 提交到数据库执行messagebox.showinfo('提示!', '删除成功!')except:con.rollback() # 发生错误时回滚messagebox.showinfo('警告!', '删除失败,数据库连接失败!')con.close() # 关闭数据库连接id_index = self.ticketid.index(self.row_info[0])print(id_index)del self.ticketid[id_index]del self.identityid[id_index]del self.idid[id_index]del self.phonee[id_index]del self.numm[id_index]del self.mm[id_index]del self.timee[id_index]print(self.ticketid)self.tree.delete(self.tree.selection()[0]) # 删除所选行print(self.tree.get_children())def back(self):TicketMessage(self.window) # 进入管理员操作界面 # 管理员操作游客信息
class YoKe:def __init__(self, parent_window):parent_window.destroy() # 自动销毁上一个界面self.window = Tk() # 初始框的声明self.window.title('管理员操作界面')self.window.geometry("900x900+300+0") # 初始窗口在屏幕中的位置self.frame_left_top = tk.Frame(width=300, height=300) # 指定框架,在窗口上可以显示,这里指定四个框架 self.frame_right_top = tk.Frame(width=300, height=300)self.frame_center = tk.Frame(width=800, height=400)self.frame_bottom = tk.Frame(width=650, height=70)# 定义下方中心列表区域self.columns = ("游客账号", "游客密码", "游客姓名", "游客性别", "联系电话" , "注册时间")self.tree = ttk.Treeview(self.frame_center, show="headings", height=30, columns=self.columns)# 添加竖直滚动条self.vbar = ttk.Scrollbar(self.frame_center, orient=VERTICAL, command=self.tree.yview)# 定义树形结构与滚动条self.tree.configure(yscrollcommand=self.vbar.set)# 定义id1为修改id时的暂存变量,这个是为了更新信息而设计的self.id1 = 0# 表格的标题self.tree.column("游客账号", width=130, anchor='center') # 表示列,不显示self.tree.column("游客密码", width=130, anchor='center')self.tree.column("游客姓名", width=130, anchor='center')self.tree.column("游客性别", width=130, anchor='center')self.tree.column("联系电话", width=130, anchor='center')self.tree.column("注册时间", width=130, anchor='center')#self.tree.column("退票时间", width=150, anchor='center')# grid方法将tree和vbar进行布局self.tree.grid(row=0, column=0, sticky=NSEW)self.vbar.grid(row=0, column=1, sticky=NS)# 定义几个数组,为中间的那个大表格做一些准备#self.id = []#self.name = []#self.gender = []#self.age = []self.ticketid = [] #游客账号self.identityid = [] #游客密码self.idid = [] #游客姓名self.phonee = [] #游客性别self.numm = [] #联系电话self.mm = [] #注册时间#self.timee = [] #订票时间# 打开数据库连接con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标sql = "SELECT * FROM 游客信息"try:# 执行SQL语句cursor.execute(sql)# 获取所有记录列表results = cursor.fetchall()for row in results:#self.id.append(row[0])#self.name.append(row[1])#self.gender.append(row[2])#self.age.append(row[3])self.ticketid.append(row[0])self.identityid.append(row[1])self.idid.append(row[2])self.phonee.append(row[3])self.numm.append(row[4])self.mm.append(row[5])#self.timee.append(row[6])except:messagebox.showinfo('警告!', '数据库连接失败!')con.close()# 关闭数据库连接print("test***********************")for i in range(min(len(self.ticketid),len(self.identityid), len(self.idid), len(self.phonee), len(self.numm),len(self.mm))): # 写入数据self.tree.insert('', i, values=(self.ticketid[i], self.identityid[i], self.idid[i], self.phonee[i], self.numm[i], self.mm[i]))for col in self.columns: # 绑定函数,使表头可排序self.tree.heading(col, text=col,command=lambda _col=col: self.tree_sort_column(self.tree, _col, False))# 定义下方区域self.chaxun = StringVar()self.right_bottom_gender_entry = Entry(self.frame_bottom, textvariable=self.chaxun, font=('Verdana', 15))self.right_bottom_button = ttk.Button(self.frame_bottom, text='游客查询', width=20, command=self.put_data)self.right_bottom_button.grid(row=0, column=0, padx=20, pady=20) # 位置设置self.right_bottom_gender_entry.grid(row=0, column=1)self.left_top_frame = tk.Frame(self.frame_left_top)self.var_ticketid = StringVar() # 声明游客账号self.var_identityid= StringVar() # 声明游客密码self.var_idid = StringVar() # 声明游客姓名self.var_phonee = StringVar() # 声明游客性别self.var_numm = StringVar() # 声明联系电话self.var_mm = StringVar() # 声明注册时间#self.var_timee = StringVar() # 声明订票时间# 定义顶部区域# 定义左上方区域self.top_title = Label(self.frame_left_top, text="游客信息:", font=('Verdana', 20))self.top_title.grid(row=0, column=0, columnspan=2, sticky=NSEW, padx=50, pady=10) # NSEW表示允许组件向4个方向都可以拉伸# 游客账号self.right_top_id_label = Label(self.frame_left_top, text="游客账号:", font=('Verdana', 15))self.right_top_id_entry = Entry(self.frame_left_top, textvariable=self.var_ticketid, font=('Verdana', 15))self.right_top_id_label.grid(row=1, column=0) # 位置设置self.right_top_id_entry.grid(row=1, column=1)# 游客密码self.right_top_id_label = Label(self.frame_left_top, text="游客密码:", font=('Verdana', 15))self.right_top_id_entry = Entry(self.frame_left_top, textvariable=self.var_identityid, font=('Verdana', 15))self.right_top_id_label.grid(row=2, column=0) # 位置设置self.right_top_id_entry.grid(row=2, column=1)# 游客姓名self.right_top_name_label = Label(self.frame_left_top, text="游客姓名:", font=('Verdana', 15))self.right_top_name_entry = Entry(self.frame_left_top, textvariable=self.var_idid, font=('Verdana', 15))self.right_top_name_label.grid(row=3, column=0) # 位置设置self.right_top_name_entry.grid(row=3, column=1)# 游客性别self.right_top_name_label = Label(self.frame_left_top, text="游客性别:", font=('Verdana', 15))self.right_top_name_entry = Entry(self.frame_left_top, textvariable=self.var_phonee, font=('Verdana', 15))self.right_top_name_label.grid(row=4, column=0) # 位置设置self.right_top_name_entry.grid(row=4, column=1)# 联系电话self.right_top_gender_label = Label(self.frame_left_top, text="联系电话:", font=('Verdana', 15))self.right_top_gender_entry = Entry(self.frame_left_top, textvariable=self.var_numm,font=('Verdana', 15))self.right_top_gender_label.grid(row=5, column=0) # 位置设置self.right_top_gender_entry.grid(row=5, column=1)# 注册时间self.right_top_gender_label = Label(self.frame_left_top, text="注册时间:", font=('Verdana', 15))self.right_top_gender_entry = Entry(self.frame_left_top, textvariable=self.var_mm,font=('Verdana', 15))self.right_top_gender_label.grid(row=6, column=0) # 位置设置self.right_top_gender_entry.grid(row=6, column=1)# 定义右上方区域self.right_top_title = Label(self.frame_right_top, text="操作:", font=('Verdana', 20))self.tree.bind('<Button-1>', self.click) # 左键获取位置(tree.bind可以绑定一系列的事件,可以搜索ttk相关参数查看)self.right_top_button1 = ttk.Button(self.frame_right_top, text='新增', width=20, command=self.new_row)self.right_top_button2 = ttk.Button(self.frame_right_top, text='更新', width=20,command=self.updata_row)self.right_top_button3 = ttk.Button(self.frame_right_top, text='注销', width=20,command=self.del_row)self.right_top_button4 = ttk.Button(self.frame_right_top, text='返回', width=20,command=self.back)# 定义下方区域,查询功能块self.chaxun = StringVar()self.right_bottom_gender_entry = Entry(self.frame_bottom, textvariable=self.chaxun, font=('Verdana', 15))self.right_bottom_button = ttk.Button(self.frame_bottom, text='查询', width=20, command=self.put_data)self.right_bottom_button.grid(row=0, column=0, padx=20, pady=20) # 位置设置self.right_bottom_gender_entry.grid(row=0, column=1)# 右上角按钮的位置设置self.right_top_title.grid(row=1, column=0, pady=10)self.right_top_button1.grid(row=2, column=0, padx=20, pady=10)self.right_top_button2.grid(row=3, column=0, padx=20, pady=10)self.right_top_button3.grid(row=4, column=0, padx=20, pady=10)self.right_top_button4.grid(row=5, column=0, padx=20, pady=10)# 整体区域定位,利用了Frame和grid进行布局self.frame_left_top.grid(row=0, column=0, padx=2, pady=5)self.frame_right_top.grid(row=0, column=1, padx=30, pady=30)self.frame_center.grid(row=1, column=0, columnspan=2, padx=4, pady=5)self.frame_bottom.grid(row=2, column=0, columnspan=2)# 设置固定组件,(0)就是将组件进行了固定self.frame_left_top.grid_propagate(0)self.frame_right_top.grid_propagate(0)self.frame_center.grid_propagate(0)self.frame_bottom.grid_propagate(0)self.frame_left_top.tkraise() # 开始显示主菜单,tkraise()提高z轴的顺序(不太懂)self.frame_right_top.tkraise() # 开始显示主菜单self.frame_center.tkraise() # 开始显示主菜单self.frame_bottom.tkraise() # 开始显示主菜单self.window.protocol("WM_DELETE_WINDOW", self.back) # 捕捉右上角关闭点击,执行back方法self.window.mainloop() # 进入消息循环# 将查到的信息放到中间的表格中def put_data(self):self.delButton() # 先将表格内的内容全部清空# print(self.chaxun.get()) # 输入框内的内容 # 打开数据库连接,准备查找指定的信息con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标#sql = "use EMIS exec proc_cha '%s'" % (self.chaxun.get())sql = "SELECT * FROM 游客信息 WHERE 游客账号 = '%s' " % (self.chaxun.get())try:# 执行SQL语句cursor.execute(sql)# 获取所有记录列表results = cursor.fetchall()# 再次进行初始化,进行首行数据的插入self.ticketid = [] #订票编号self.identityid = [] #游客账号self.idid = [] #身份证号self.phonee = [] #联系电话self.numm = [] #订票数量self.mm = [] #应付金额#self.timee = [] #订票时间for row in results:self.ticketid.append(row[0])self.identityid.append(row[1])self.idid.append(row[2])self.phonee.append(row[3])self.numm.append(row[4])self.mm.append(row[5])#self.timee.append(row[6])except:print("Error: unable to fetch data")messagebox.showinfo('警告!', '数据库连接失败!')con.close()# 关闭数据库连接print("进行数据的插入")for i in range(min(len(self.ticketid),len(self.identityid), len(self.idid), len(self.phonee), len(self.numm),len(self.mm))): # 写入数据self.tree.insert('', i, values=(self.ticketid[i], self.identityid[i], self.idid[i], self.phonee[i], self.numm[i], self.mm[i]))for col in self.columns: # 绑定函数,使表头可排序self.tree.heading(col, text=col,command=lambda _col=col: self.tree_sort_column(self.tree, _col, False))# 清空表格中的所有信息def delButton(self):x=self.tree.get_children()for item in x:self.tree.delete(item)# 在表格上的点击事件,这里是作用就是一点击表格就可以将信息直接写到左上角的框框中def click(self, event):self.col = self.tree.identify_column(event.x) # 通过tree.identify_column()函数可以直接获取到列self.row = self.tree.identify_row(event.y) # 行print(self.col)print(self.row)self.row_info = self.tree.item(self.row, "values")self.var_ticketid.set(self.row_info[0])self.id1 = self.var_ticketid.get()self.var_identityid.set(self.row_info[1])self.var_idid.set(self.row_info[2])self.var_phonee.set(self.row_info[3])self.var_numm.set(self.row_info[4])self.var_mm.set(self.row_info[5])#self.var_timee.set(self.row_info[6])self.right_top_id_entry = Entry(self.frame_left_top, state='disabled', textvariable=self.var_ticketid, font=('Verdana', 15))# 点击中间的表格的表头,可以将那一列进行排序def tree_sort_column(self, tv, col, reverse): # Treeview、列名、排列方式l = [(tv.set(k, col), k) for k in tv.get_children('')]l.sort(reverse=reverse) # 排序方式for index, (val, k) in enumerate(l): # 根据排序后索引移动tv.move(k, '', index)tv.heading(col, command=lambda: self.tree_sort_column(tv, col, not reverse)) # 重写标题,使之成为再点倒序的标题#注册 def new_row(self):self.delButton() # 先将表格内的内容全部清空print('123')#print(self.var_ticketid.get())#print(self.ticketid)if self.var_identityid.get() not in self.identityid:messagebox.showinfo('警告!', '请输入您的账号!')elif (len(str(self.var_numm.get())) > 15) or (len(str(self.var_numm.get())) < 7):messagebox.showinfo('警告!', '请输入正确的手机号!')else:if self.var_identityid.get() != '' and self.var_idid.get() != '' and self.var_phonee.get() != '' and self.var_numm.get() != '':# 打开数据库连接con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标sql = "INSERT INTO 游客信息(游客账号,游客密码,游客姓名,游客性别,联系电话) \VALUES ('%s', '%s', '%s', '%s', '%s')" % \(self.var_ticketid.get(), self.var_identityid.get(), self.var_idid.get(), self.var_phonee.get(), self.var_numm.get()) # SQL 插入语句try:cursor.execute(sql) # 执行sql语句con.commit() # 提交到数据库执行except:con.rollback() # 发生错误时回滚messagebox.showinfo('警告!', '数据库连接失败!')con.close() # 关闭数据库连接# 向表格中插入数据con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标#sql = "use EMIS exec proc_cha '%s'" % (self.chaxun.get())sql = "SELECT * FROM 游客信息" try:# 执行SQL语句cursor.execute(sql)# 获取所有记录列表results = cursor.fetchall()# 再次进行初始化,进行首行数据的插入self.ticketid = [] #游客账号self.identityid = [] #游客密码self.idid = [] #游客姓名self.phonee = [] #游客性别self.numm = [] #联系电话self.mm = [] #注册时间#self.timee = [] #订票时间for row in results:self.ticketid.append(row[0])self.identityid.append(row[1])self.idid.append(row[2])self.phonee.append(row[3])self.numm.append(row[4])self.mm.append(row[5])#self.timee.append(row[6])except:print("Error: unable to fetch data")messagebox.showinfo('警告!', '数据库连接失败!')con.close()# 关闭数据库连接print("进行数据的插入")for i in range(min(len(self.ticketid),len(self.identityid), len(self.idid), len(self.phonee), len(self.numm),len(self.mm))): # 写入数据self.tree.insert('', i, values=(self.ticketid[i], self.identityid[i], self.idid[i], self.phonee[i], self.numm[i], self.mm[i]))for col in self.columns: # 绑定函数,使表头可排序self.tree.heading(col, text=col,command=lambda _col=col: self.tree_sort_column(self.tree, _col, False))self.tree.update() messagebox.showinfo('提示!', '注册成功!')else:messagebox.showinfo('警告!', '请填写正确信息')#更新def updata_row(self):self.delButton() # 先将表格内的内容全部清空res = messagebox.askyesnocancel('警告!', '是否更新所填数据?')if res == True:if self.var_ticketid.get() == self.row_info[0] and self.var_identityid.get() ==self.row_info[1]: # 如果所填学号 与 所选学号一致# 打开数据库连接con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标sql = "UPDATE 游客信息 SET 游客密码 = '%s', 游客姓名 = '%s', 游客性别 = '%s', 联系电话 = '%s'\WHERE 游客账号 = '%s'" % (self.var_identityid.get(), self.var_idid.get(), self.var_phonee.get(),self.var_numm.get(), self.var_ticketid.get()) # SQL 插入语句if (len(str(self.var_numm.get())) >15) or (len(str(self.var_numm.get())) <7):messagebox.showinfo('提示!', '请填写正确的手机号!')try:cursor.execute(sql) # 执行sql语句con.commit() # 提交到数据库执行messagebox.showinfo('提示!', '更新成功!')except:con.rollback() # 发生错误时回滚messagebox.showinfo('警告!', '更新失败,数据库连接失败!')con.close() # 关闭数据库连# 向表格中插入数据con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')cursor = con.cursor() # 使用cursor()方法获取操作游标#sql = "use EMIS exec proc_cha '%s'" % (self.chaxun.get())sql = "SELECT * FROM 游客信息" try:# 执行SQL语句cursor.execute(sql)# 获取所有记录列表results = cursor.fetchall()# 再次进行初始化,进行首行数据的插入self.ticketid = [] #订票编号self.identityid = [] #游客账号self.idid = [] #身份证号self.phonee = [] #联系电话self.numm = [] #订票数量self.mm = [] #应付金额#self.timee = [] #订票时间for row in results:self.ticketid.append(row[0])self.identityid.append(row[1])self.idid.append(row[2])self.phonee.append(row[3])self.numm.append(row[4])self.mm.append(row[5])#self.timee.append(row[6])except:print("Error: unable to fetch data")messagebox.showinfo('警告!', '数据库连接失败!')con.close()# 关闭数据库连接print("进行数据的插入")for i in range(min(len(self.ticketid),len(self.identityid), len(self.idid), len(self.phonee), len(self.numm),len(self.mm))): # 写入数据self.tree.insert('', i, values=(self.ticketid[i], self.identityid[i], self.idid[i], self.phonee[i], self.numm[i], self.mm[i]))for col in self.columns: # 绑定函数,使表头可排序self.tree.heading(col, text=col,command=lambda _col=col: self.tree_sort_column(self.tree, _col, False))self.tree.update() #messagebox.showinfo('提示!', '更新成功!')# 删除行def del_row(self):res = messagebox.askyesnocancel('警告!', '是否删除所选数据?')if res == True:print(self.row_info[0]) # 鼠标选中的学号print(self.tree.selection()[0]) # 行号print(self.tree.get_children()) # 所有行# 打开数据库连接con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8') cursor = con.cursor() # 使用cursor()方法获取操作游标#sql = "use EMIS exec proc_delete '%s'" % (self.row_info[0]) # SQL 插入语句sql = "DELETE FROM 游客信息 WHERE 游客账号 = '%s'" % (self.row_info[0]) # SQL 插入语句try:cursor.execute(sql) # 执行sql语句con.commit() # 提交到数据库执行messagebox.showinfo('提示!', '删除成功!')except:con.rollback() # 发生错误时回滚messagebox.showinfo('警告!', '删除失败,数据库连接失败!')con.close() # 关闭数据库连接id_index = self.ticketid.index(self.row_info[0])print(id_index)del self.ticketid[id_index]del self.identityid[id_index]del self.idid[id_index]del self.phonee[id_index]del self.numm[id_index]del self.mm[id_index]#del self.timee[id_index]print(self.ticketid)self.tree.delete(self.tree.selection()[0]) # 删除所选行print(self.tree.get_children())def back(self):TicketMessage(self.window) # 进入管理员子菜单操作界面 #关于
class AboutPage:def __init__(self, parent_window):parent_window.destroy() # 销毁主界面self.window = tk.Tk() # 初始框的声明self.window.title('关于')self.window.geometry('900x900') # 这里的乘是小xself.window.geometry('+330+0')label = tk.Label(self.window, text='景点门票销售管理系统', bg='green', font=('Verdana', 20), width=30, height=2)label.pack()Label(self.window, text='作者:正大的光', font=('Verdana', 20)).pack(pady=30)Label(self.window, text='版本:0.0.0.1', font=('Verdana', 20)).pack(pady=30)Button(self.window, text="返回首页", width=8, font=tkFont.Font(size=15), command=self.back).pack(pady=100)self.window.protocol("WM_DELETE_WINDOW", self.back) # 捕捉右上角关闭点击self.window.mainloop() # 进入消息循环def back(self):StartPage(self.window) # 显示主窗口 销毁本窗口win = tk.Tk()
StartPage(win)
3、基于Python3中tkinte的笔记
此处381行
#python3代码笔记#
PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,Python2中则使用mysqldb。
PyMySQL 遵循 Python 数据库 API v2.0 规范,并包含了 pure-Python MySQL 客户端库。在安装python路径下安装PyMySQL
pip3 install PyMySQL#
Tkinter 是 Python 的标准 GUI 库。Python 使用 Tkinter 可以快速的创建 GUI 应用程序。
Python3.x 版本使用的库名为 tkinter,即首写字母 T 为小写。由于 Tkinter 是内置到 python 的安装包中、只要安装好 Python 之后就能 import Tkinter 库、而且 IDLE 也是用 Tkinter 编写而成、对于简单的图形界面 Tkinter 还是能应付自如。应该算是tkinter的一个进阶组件,为的,就是完善tkinter的一些功能。
二者都有的组件,ttk将会覆盖Tkinter;ttk有而Tkinter没有的,将采用ttk的特性。#
con = pymysql.connect(host='localhost',port=3306,user='root',passwd='CYFF',db='景点门票销售管理系统',charset='utf8')#连接数据库
con = pymysql.connect(host='主机名',port=端口,user='Mysql用户名',password='用户密码',db='要连接的数据库名',charset='字符集'
)con.commit() #提交到数据库执行,如果是修改,更新等操作,需要提交,不然无法保存新建或者修改的数据con.rollback() # 发生错误时回滚,不提交事务,可以理解为撤回。con.close() # 关闭数据库连接#
游标(cursor)
对数据库进行具体的操作了,比如增、删、改、查等等一系列操作都可以完成。
定位到结果集中的某一行;对当前位置的数据进行读写;可以对结果集中的数据单独操作,而不是整行执行相同的操作;是面向集合的数据库管理系统和面向行的程序设计之间的桥梁。cursor = connect.cursor() #获取游标游标默认获取的数据是元组类型,如果想要字典类型的数据可以使用:
cursor = connect.cursor(cursor=pymysql.cursors.DictCursor)effect_row = cursor.execute("SELECT * FROM 表 WHERE 字段 = %s") #执行SQL,并返回受影响的行数
为了防止数据库查询发生SQL注入的攻击,可以使用%s占位符来转义查询的条件。要接收的参数都用%s占位符.要注意的是,无论你要插入的数据是什么类型,占位符永远都要用%srows = cursor.fetchall() #获取所有数据
row_1 = cursor.fetchone() #获取第一行数据
row_n = cursor.fetchmany(n) #获取前n行数据cursor.close() #关闭游标#
tkinter.messagebox 模块提供了一个模板基类以及多个常用配置的便捷方法。 消息框为模式窗口并将基于用户的选择返回 (True, False, OK, None, Yes, No) 的一个子集。信息消息框
import tkinter.messagebox as messagebox
messagebox.showinfo(title="信息",message="hello")警告消息框
messagebox.showwarning(title="警告", message="hello")
messagebox.showerror(title="错误", message="hello")
messagebox.askquestion(title="是否", message="hello")疑问消息框
messagebox.askokcancel(title="确认取消", message="hello")
messagebox.askretrycancel(title="重试取消", message="hello")
messagebox.askyesno(title="是否", message="hello")
messagebox.askyesnocancel(title="是否取消", message="hello")#
destroy()是一种通用的窗口小部件方法,即我们可以将此方法与任何可用的窗口小部件以及主tkinter窗口一起使用。可以销毁窗口。#
建立根窗口
引入模块
import tkinter
root = tkinter.Tk()
或者
引入模块中的所有类
from tkinter import *
root = Tk()#
self.window = tk.Tk() # 建立根窗口
self.window.title('界面名称') # 设置界面名称
self.window.geometry('数字x数字') # 设置窗口的宽和高,这里的乘是小写字母x
self.window.geometry('+数字+数字')# 第1个加号是距离屏幕左边的宽,第2个加号是距离屏幕顶部的高。通过geometry函数来设置窗口的宽和高,就算窗口已经通过resizable函数禁止调整宽高;还可以移动窗口在屏幕上的位置,加号后面可以跟负数。#
self.window.mainloop() # 主消息循环
作用就是回到代码头部,检测下一次点鼠标,对我们的循环操作进行循环。#
self.window.protocol("WM_DELETE_WINDOW", self.back) # 捕捉右上角关闭点击def back(self):StartPage(self.window) # 显示主窗口 销毁本窗口监听窗口window的右上角的'x'事件,当点击'x'时,绑定一个事件 back,其中"WM_DELETE_WINDOW"是参数,此处不需要改。
用于定义当用户使用窗口管理器显式关闭窗口时发生的情况。#
Button(self.window, text="管理员登陆", font=tkFont.Font(size=25), command=lambda: AdminPage(self.window), width=60, height=2,fg='white',bg='gray',activebackground='black', activeforeground='white').pack()用于在Python应用程序中添加按钮,按钮上可以放上文本或图像,可用于监听用户行为,能够与一个Python 函数关联,当按钮被按下时,自动调用该函数。基本语法:Button(根对象, 属性)
根对象:在哪个窗体显示,例如主窗体。按钮的父容器。
属性:可选的属性=属性值。可选属性:
activebackground 当鼠标放上去时,按钮的背景色
activeforeground 当鼠标放上去时,按钮的前景色
bd 按钮边框的大小,默认为 2 个像素
bg 按钮的背景色
command 按钮关联的函数,当按钮被点击时,执行该函数
fg 按钮的前景色(按钮中文本的颜色)
text 按钮显示的文本
font 文本字体和大小
height 按钮的高度,一个中文的字体高为单位
highlightcolor 要高亮的颜色
image 按钮上要显示的图片
justify 显示多行文本的时候,设置不同行之间的对齐方式,可选项包括LEFT, RIGHT, CENTER
padx 按钮在x轴方向上的内边距(padding),是指按钮的内容与按钮边缘的距离
pady 按钮在y轴方向上的内边距(padding)
relief 边框样式,设置控件3D效果,可选的有:FLAT、SUNKEN、RAISED、GROOVE、RIDGE。默认为 FLAT。
state 设置按钮组件状态,可选的有NORMAL、ACTIVE、 DISABLED。默认 NORMAL。
underline 下划线。默认按钮上的文本都不带下划线。取值就是带下划线的字符串索引,为 0 时,第一个字符带下划线,为 1 时,前两个字符带下划线,以此类推。
width 按钮的宽度,如未设置此项,其大小以适应按钮的内容(文本或图片的大小)一个中文的字体宽为单位
wraplength 限制按钮每行显示的字符的数量
anchor 锚选项,控制文本的位置,默认值是 "center"
cursor 鼠标的样式
compound 图片与文字的混搭pack中的padx是严格控制控件之间的距离的;
button中的width是根据字符控制控件大小;
button中的padx是根据像素控制控件大小。以上参考菜鸟#
使用font字体参数,来控制控件上显示的字体,大小和样式。
例:font = tkFont.Font(family = 'Fixdsys' ,size = 20 ,weight = tkFont.BOLD)#
只引入模块
label = tk.Label(window,text='我是标签', #text为显示的文本内容bg='black',fg='white', #bg为背景色,fg为前景色font=("华文行楷", 20), #设置字体为“华文行楷”,大小为20width=20,height=5) #width为标签的宽,height为高Label用于需要显示一行或多行文本且不允许用户修改anchor 文本或图像在背景内容区的位置,默认为 center,可选值为(n,s,w,e,ne,nw,sw,se,center)eswn
bg 标签背景颜色
bd 标签的大小,默认为 2 个像素
bitmap 指定标签上的位图,如果指定了图片,则该选项忽略
cursor 鼠标移动到标签时,光标的形状,可以设置为 arrow, circle, cross, plus 等。
font 设置字体。
fg 设置前景色。
height 标签的高度,默认值是 0。
image 设置标签图像。
justify 定义对齐方式,可选值有:LEFT,RIGHT,CENTER,默认为 CENTER。
padx x 轴间距,以像素计,默认 1。
pady y 轴间距,以像素计,默认 1。
relief 边框样式,可选的有:FLAT、SUNKEN、RAISED、GROOVE、RIDGE。默认为 FLAT。
text 设置文本,可以包含换行符(\n)。
textvariable 标签显示 Tkinter 变量,StringVar。如果变量被修改,标签文本将自动更新。
underline 设置下划线,默认 -1,如果设置 1,则是从第二个字符开始画下划线。
width 设置标签宽度,默认值是 0,自动计算,单位以像素计。
wraplength 设置标签文本为多少行显示,默认为 0。以上参考菜鸟#
有引入tk类
pack() 几何图形管理器 将小部件打包为行或列 创建浮动,自动伸缩扩展的软件界面label = Label(self.window, text="景点门票销售管理系统", font=("Verdana", 40))
label.pack(pady=100) # pady=100 界面的长度label.pack(side = TOP, expand = True, fill = BOTH)
label.pack(anchor=S, side=TOP, ipady=2, pady=2, fill=NONE)anchor 一共有8个参数可选,分别是:n,ne,e,se,s,sw,w,nw,即北,东北,东,东南,南,西南,西,西北。其中n是north,s是south,e是east,w是weast。
side 确定父窗口小部件的哪一侧打包:TOP(默认),BOTTOM,LEFT或RIGHT。即顶部,底部,左,右。
expand 设置为true时,窗口小部件将展开以填充窗口小部件父级中未使用的任何空间。
fill 确定小部件是否填充由打包器分配给它的任何额外空间,或保持其自己的最小尺寸:NONE(默认),X(仅水平填充),Y(仅垂直填充)或BOTH(水平和垂直填充) )。fill的填充,一般用来填充父框架。
padx,pady,ipadx,ipady不仅可以用于父框架的填充显示,更多用于子框架的填充显示。
padx和pady用于设置框架的外部填充显示。
ipadx和ipady用于设置框架的内部显示。#
self.admin_username = tk.Entry(self.window, width=30, font=tkFont.Font(size=14), bg='Ivory')Entry文本框用来让用户输入一行文本字符串。
基本语法:Entry(根对象, 属性)
根对象:在哪个窗体显示,例如主窗体。按钮的父容器。
属性:可选的属性=属性值。并以逗号分隔。可选属性:
bg 输入框背景颜色
bd 边框的大小,默认为 2 个像素
cursor 光标的形状设定,如arrow, circle, cross, plus 等
font 文本字体
exportselection 默认情况下,你如果在输入框中选中文本,默认会复制到粘贴板,如果要忽略这个功能设置 exportselection=0。
fg 文字颜色。值为颜色或为颜色代码,如:'red','#ff0000'
highlightcolor 文本框高亮边框颜色,当文本框获取焦点时显示
justify 显示多行文本的时候,设置不同行之间的对齐方式,可选项包括LEFT, RIGHT, CENTER
relief 边框样式,设置控件3D效果,可选的有:FLAT、SUNKEN、RAISED、GROOVE、RIDGE。默认为 FLAT。
selectbackground 选中文字的背景颜色
selectborderwidth 选中文字的背景边框宽度
selectforeground 选中文字的颜色
show 指定文本框内容显示为字符,值随意,满足字符即可。如密码可以将值设为 show="*"
state 默认为 state=NORMAL, 文框状态,分为只读和可写,值为:normal/disabled
textvariable 文本框的值,是一个StringVar()对象
width 文本框宽度
xscrollcommand 设置水平方向滚动条,一般在用户输入的文本框内容宽度大于文本框显示的宽度时使用。以上参考菜鸟#
get先获取到内容,再判断。
self.admin_username = tk.Entry(self.window, width=30, font=tkFont.Font(size=14), bg='Ivory')
print(str(self.admin_username.get()))tkinter.Text.get(x.y, end) 其中x为行号,y为该行上的字符位置号。,第二个End表示最后一个字符,#
(Frame)框架控件在屏幕上显示一个矩形区域,多用来作为容器。主要用于在复杂的布局中将其他组件分组,也用于填充间距和作为实现高级组件的基类。self.frame_left_top = tk.Frame(width=300, height=300)
基本语法:Entry( 框架的父容器, 属性)
框架的父容器:在哪个窗体显示,例如主窗体。
属性:可选的属性=属性值。并以逗号分隔。bg 框架背景颜色
bd 框架的大小,默认为 2 个像素
cursor 鼠标移动到框架时,光标的形状,可以设置为 arrow, circle, cross, plus 等。
height 框架的高度,默认值是 0。
highlightbackground 框架没有获得焦点时,高亮边框的颜色,默认由系统指定。
highlightcolor 框架获得焦点时,高亮边框的颜色
highlightthickness 指定高亮边框的宽度,默认值为 0不带高亮边框)
relief 边框样式,可选的有:FLAT、SUNKEN、RAISED、GROOVE、RIDGE。默认为 FLAT。
width 设置框架宽度,默认值是 0。
takefocus 指定该组件是否接受输入焦点(用户可以通过 tab 键将焦点转移上来),默认为 false。#
self.tree =ttk.Treeview(self.frame_center,show="headings",height=18,columns=self.columns)树视图(ttk.Treeview)是树形图和列表相结合,可以显示并允许浏览item的层次结构,并可以将每个item的一个或多个属性显示为树右侧的列,即第一列是它的树状结构,后面几列的是列表结构。ttk.Treeview(父控件, 属性)
属性:show 使标签在每一列的顶部,指定显示=‘树’。默认是显示列标签。设置show属性为 headings可隐藏首列。
height 表示要显示几行数据。
columns 值是一个列表,列表里每个元素代表一个列标识符的名称,以确定控件中的列,列表的长度为列的长度。#???
self.vbar = ttk.Scrollbar(self.frame_center, orient=VERTICAL, command=self.tree.yview)形式:Scrollbar(父组件, 属性)
orient 指定绘制"horizontal"(垂直滚动条)还是"vertical"(水平滚动条),默认值是VERTICAL
command 当滚动条更新时回调的函数,通常的是指定对应组件的xview()或yview()方法self.tree.configure(yscrollcommand=self.vbar.set) # 定义树形结构与滚动条,即设置部件的外观和行为。在组件上安装垂直滚动条
设置组件的yscrollbarcommand选项为Scrollbar组件的set()方法;
设置Scrollbar组件的command选项为该组件的yview()方法。
水平滚动条方法跟上边一样,只是将 yscrollcommand 改为 xscrollcommand,yview 改为 xview 即可。
xview(*args) 方法用于在水平方向上滚动Canvas组件的内容,一般通过绑定Scollbar组件的command选项来实现。
yview(*args) 方法用于在垂直方向上滚动Canvas组件的内容一般通过绑定Scollbar组件的command选项来实现。#
self.tree.grid(row=0, column=0, sticky=NSEW)
Grid(网格)布局管理器会将控件放置到一个二维的表格里,主控件被分割成一系列的行和列,表格中的每个单元都可以放置一个控件。形式:.grid(属性)
属性:
row 插件布放的行数值,从0开始。默认值为未布放行的下一个数值。
column 插件布放的列数值,从0开始。默认值为0。
sticky 在插件正常尺寸下,分配单元多余的空间。还是使用nswb。上北下南,左西右东。
ipadx x方向的内部填充。在插件内部,左右方向各填充指定长度的空间。
ipady y方向的内部填充。在插件内部,上下方向各填充指定长度的空间。
padx x方向的外部填充。在插件外部,左右方向各填充指定长度的空间。
pady y方向的内部填充。在插件内部,上下方向各填充指定长度的空间。#
for i in range(min(len(self.id),len(self.passd), len(self.name), len(self.sex), len(self.phone),len(self.jid))): # 写入数据self.tree.insert('', i, values=(self.id[i], self.passd[i], self.name[i], self.sex[i], self.phone[i], self.jid[i]))返回的是一个可迭代对象(类型是对象),而不是列表类型。Python2 range() 函数返回的是列表。#
self.tree.heading(col, text=col,command=lambda _col=col: self.tree_sort_column(self.tree, _col, False)) #定义顶部区域#
self.var_adminid = StringVar() # 声明管理员账号#
self.tree.bind('<Button-1>', self.click) # 左键获取位置,即鼠标左键单击按下#
self.frame_left_top.grid_propagate(0)
根据内容自动调整大小。有时候想要固定插件的大小。可以通过.grid_propagate(0)来实现。#
self.frame_left_top.tkraise() # 开始显示主菜单
使多个 tkinter.Frame 的可见性得以切换。#
self.col = self.tree.identify_column(event.x) # 标识列
event.x 设置或者是得到鼠标相对于目标事件的父元素的外边界在x坐标上的位置。#
self.row_info = self.tree.item(self.row, "values") #键和键值#
l = [(tv.set(k, col), k) for k in tv.get_children('')]
treeview中set(item,column,value)函数中,item是get_children()返回的记录号,column是treeview的列名。#
for index, (val, k) in enumerate(l): # 根据排序后索引移动tv.move(k, '', index)tv.heading(col, command=lambda: self.tree_sort_column(tv, col, not reverse)) # 重写标题,使之成为再点倒序的标题enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。参数为可遍历的变量,如 字符串,列表等; 返回值为enumerate类。#
print(self.tree.get_children()) # 所有行#
self.tree.delete(self.tree.selection()[0]) # 删除所选行
4、部分窗口图示
sqlyog里的报表
景点门票销售管理系统 基于 python实现gui界面 之 笔记相关推荐
- 景点门票销售系统系统java_某景点门票销售管理系统
[实例简介] 可用于学校实训课大作业,有数据库有文档 可用于学校实训课大作业,有数据库有文档 可用于学校实训课大作业,有数据库有文档 可用于学校实训课大作业,有数据库有文档 [实例截图] [核心代码] ...
- Python之GUI:基于Python的GUI界面设计的一套AI课程学习(机器学习、深度学习、大数据、云计算等)推荐系统(包括语音生成、识别等前沿黑科技)
Python之GUI:基于Python的GUI界面设计的一套AI课程学习(机器学习.深度学习.大数据.云计算等)推荐系统(包括语音生成.识别等前沿黑科技) 导读 基于Python的GUI界面设计的一套 ...
- python+vue塔尔寺景点门票销售管理系统
后端: 景区信息管理:可以对景区的信息进行管理,实现景区的增加,修改和删除操作,对景区的景点信息,照片进行上传,实现景区的发布. 门票预订管理:对门票的预订信息,进行在线的查看,并且可以审核. 订单管 ...
- SQL server课程设计-景点门票销售管理系统(基于Javagui制作)
目前各个高校的课程设计题目大都是某某某管理系统,这些管理系统都有异曲同工之妙,大都是万变不离其中,这里为大家带来的是景点门票销售系统,希望对大家有所帮助哦,有问题直接私信我或者评论区找我即可. 本景点 ...
- 基于Python实现 GUI界面 计算传感器的连接率 传感网通信连结仿真
输出截图 算法还在优化中,python真是世界上最美丽的语言(●ˇ∀ˇ●) 20/11/22更新源代码: import tkinter as tk from tkinter import ttk # ...
- javaweb课程设计景点门票销售系统
随着互联网络的快速发展,计算机技术迅速渗入到各行各业,为很多很多的用户提供了更加周到更加便捷的服务.当今世界,越来越多的行业都会采用专业的系统去给大家提供方便,其范围包括了教育科研.文化事业.金融.商 ...
- Python四行代码实现的猜数字小游戏,基于thinker,带GUI界面
Python四行代码实现的猜数字小游戏,基于thinker,带GUI界面 from tkinter import * from tkinter import messagebox 导入提示框 from ...
- python界面开发 web_使用 web 技术构建 python 的 GUI 界面
一般来说,选择用于应用程序的 GUI 工具箱会是一个棘手的事情,Python 也不例外.对于 Python 来说,可以选择的工具箱种类繁多.就我所知道的而言,比较常用的就有 TkInter, wxPy ...
- python中的gui界面编程_python应用系列教程——python的GUI界面编程Tkinter全解
全栈工程师开发手册 (作者:栾鹏) python的GUI界面编程,常用的几个python库包含如下: Tkinter: Tkinter 模块(Tk 接口)是 Python 的标准 Tk GUI 工具包 ...
最新文章
- 【数据挖掘】关联规则挖掘 Apriori 算法 ( 关联规则简介 | 数据集 与 事物 Transaction 概念 | 项 Item 概念 | 项集 Item Set | 频繁项集 | 示例解析 )
- Django---Mysql数据库链接
- 前端常用linux命令
- css媒体查询(手机、平板、PC)
- eemd优缺点_基于EEMD的信号处理方法分析和实现
- 位运算 进制转化 STL中bitset用法
- java 线程间通信方式_「转」JAVA多线程之线程间的通信方式
- 2018 【第九届蓝桥杯省赛】 C/C++ B组
- HashMap源码阅读
- 1146 mysql_MySQL错误处理--1146错误
- Android Studio 微信登录
- 基于android的学生考勤请假app
- SkyEye天目全数字实时仿真软件功能介绍
- 【转载】AE表达式中英文对照
- 百度Sugar BI 数据可视化里的标签页组件如何实现
- int数据类型的取值范围是多少?怎么计算的?
- 卷积神经网络 神经网络,卷积神经网络基础知识
- scrollToBottom
- android 弹出窗口
- c语言读取24位BMP文件并实现翻转90度、180度、270度
热门文章
- 从哈佛退休!顶尖学者丘成桐全职任教清华
- 菜鸟打造智慧物流平台 引领物流新风潮
- Druid以及监控界面的使用
- maven获取所有依赖项
- 4核处理器_【装机帮扶站】第489期:盘点一波100元以下的4核/6核/8核/10核/12核处理器(2)...
- 【企业邮箱申请】网易企业邮箱陌生人来信安全提醒功能
- 隐藏a标签html,a标签显示隐藏 js怎么控制a标签的显示和隐藏
- 双 JK 触发器 74LS112 逻辑功能。真值表_【第十章】触发器和事件
- 顺序栈(含有栈顶指针,栈底指针)的实现以及编写过程中的一些疑惑的解决
- C++中的tolower()函数与toupper()函数