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界面 之 笔记相关推荐

  1. 景点门票销售系统系统java_某景点门票销售管理系统

    [实例简介] 可用于学校实训课大作业,有数据库有文档 可用于学校实训课大作业,有数据库有文档 可用于学校实训课大作业,有数据库有文档 可用于学校实训课大作业,有数据库有文档 [实例截图] [核心代码] ...

  2. Python之GUI:基于Python的GUI界面设计的一套AI课程学习(机器学习、深度学习、大数据、云计算等)推荐系统(包括语音生成、识别等前沿黑科技)

    Python之GUI:基于Python的GUI界面设计的一套AI课程学习(机器学习.深度学习.大数据.云计算等)推荐系统(包括语音生成.识别等前沿黑科技) 导读 基于Python的GUI界面设计的一套 ...

  3. python+vue塔尔寺景点门票销售管理系统

    后端: 景区信息管理:可以对景区的信息进行管理,实现景区的增加,修改和删除操作,对景区的景点信息,照片进行上传,实现景区的发布. 门票预订管理:对门票的预订信息,进行在线的查看,并且可以审核. 订单管 ...

  4. SQL server课程设计-景点门票销售管理系统(基于Javagui制作)

    目前各个高校的课程设计题目大都是某某某管理系统,这些管理系统都有异曲同工之妙,大都是万变不离其中,这里为大家带来的是景点门票销售系统,希望对大家有所帮助哦,有问题直接私信我或者评论区找我即可. 本景点 ...

  5. 基于Python实现 GUI界面 计算传感器的连接率 传感网通信连结仿真

    输出截图 算法还在优化中,python真是世界上最美丽的语言(●ˇ∀ˇ●) 20/11/22更新源代码: import tkinter as tk from tkinter import ttk # ...

  6. javaweb课程设计景点门票销售系统

    随着互联网络的快速发展,计算机技术迅速渗入到各行各业,为很多很多的用户提供了更加周到更加便捷的服务.当今世界,越来越多的行业都会采用专业的系统去给大家提供方便,其范围包括了教育科研.文化事业.金融.商 ...

  7. Python四行代码实现的猜数字小游戏,基于thinker,带GUI界面

    Python四行代码实现的猜数字小游戏,基于thinker,带GUI界面 from tkinter import * from tkinter import messagebox 导入提示框 from ...

  8. python界面开发 web_使用 web 技术构建 python 的 GUI 界面

    一般来说,选择用于应用程序的 GUI 工具箱会是一个棘手的事情,Python 也不例外.对于 Python 来说,可以选择的工具箱种类繁多.就我所知道的而言,比较常用的就有 TkInter, wxPy ...

  9. python中的gui界面编程_python应用系列教程——python的GUI界面编程Tkinter全解

    全栈工程师开发手册 (作者:栾鹏) python的GUI界面编程,常用的几个python库包含如下: Tkinter: Tkinter 模块(Tk 接口)是 Python 的标准 Tk GUI 工具包 ...

最新文章

  1. 【数据挖掘】关联规则挖掘 Apriori 算法 ( 关联规则简介 | 数据集 与 事物 Transaction 概念 | 项 Item 概念 | 项集 Item Set | 频繁项集 | 示例解析 )
  2. Django---Mysql数据库链接
  3. 前端常用linux命令
  4. css媒体查询(手机、平板、PC)
  5. eemd优缺点_基于EEMD的信号处理方法分析和实现
  6. 位运算 进制转化 STL中bitset用法
  7. java 线程间通信方式_「转」JAVA多线程之线程间的通信方式
  8. 2018 【第九届蓝桥杯省赛】 C/C++ B组
  9. HashMap源码阅读
  10. 1146 mysql_MySQL错误处理--1146错误
  11. Android Studio 微信登录
  12. 基于android的学生考勤请假app
  13. SkyEye天目全数字实时仿真软件功能介绍
  14. 【转载】AE表达式中英文对照
  15. 百度Sugar BI 数据可视化里的标签页组件如何实现
  16. int数据类型的取值范围是多少?怎么计算的?
  17. 卷积神经网络 神经网络,卷积神经网络基础知识
  18. scrollToBottom
  19. android 弹出窗口
  20. c语言读取24位BMP文件并实现翻转90度、180度、270度

热门文章

  1. 从哈佛退休!顶尖学者丘成桐全职任教清华
  2. 菜鸟打造智慧物流平台 引领物流新风潮
  3. Druid以及监控界面的使用
  4. maven获取所有依赖项
  5. 4核处理器_【装机帮扶站】第489期:盘点一波100元以下的4核/6核/8核/10核/12核处理器(2)...
  6. 【企业邮箱申请】网易企业邮箱陌生人来信安全提醒功能
  7. 隐藏a标签html,a标签显示隐藏 js怎么控制a标签的显示和隐藏
  8. 双 JK 触发器 74LS112 逻辑功能。真值表_【第十章】触发器和事件
  9. 顺序栈(含有栈顶指针,栈底指针)的实现以及编写过程中的一些疑惑的解决
  10. C++中的tolower()函数与toupper()函数