from tkinter import *
from tkinter import ttk
from tkinter import messagebox # 导入提示窗口包
from connect_mysql import Mysql_conn
from dLink import DouLink, Node
def run_nn():
# 设置窗口大小
def center_window(root, width, height):
screenwidth = root.winfo_screenwidth()
screenheight = root.winfo_screenheight()
size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
root.geometry(size)
class GUI:
"""给每个组件都命名是为了以后迭代方便"""
def __init__(self, root):
# 创建双向链表
self.dl = DouLink()
root.title('学生信息管理系统 ')
# 设置窗口大小
center_window(root, 800, 600)
root.maxsize(1200, 800)
root.minsize(300, 240)
root.iconbitmap('1.png')
# 添加学员
upload_label_1 = ttk.Label(root, text='姓名').grid(row=0, column=1)
upload_label_2 = ttk.Label(root, text='年龄').grid(row=1, column=1)
upload_label_3 = ttk.Label(root, text='电话号码').grid(row=2, column=1)
upload_label_4 = ttk.Label(root, text='入学日期').grid(row=3, column=1)
upload_label_5 = ttk.Label(root, text='邮箱').grid(row=4, column=1)
upload_entry_1 = ttk.Entry(root)
upload_entry_2 = ttk.Entry(root)
upload_entry_3 = ttk.Entry(root)
upload_entry_4 = ttk.Entry(root)
upload_entry_5 = ttk.Entry(root)
upload_entry_1.grid(row=0, column=2)
upload_entry_2.grid(row=1, column=2)
upload_entry_3.grid(row=2, column=2)
upload_entry_4.grid(row=3, column=2)
upload_entry_5.grid(row=4, column=2)
upload_button_1 = ttk.Button(root, text="提交信息", command=lambda: upload_event()).grid(row=6, column=2)
# 修改信息
update_label_1 = ttk.Label(root, text='需更新学号').grid(row=0, column=3)
update_label_2 = ttk.Label(root, text='姓名').grid(row=1, column=3)
update_label_3 = ttk.Label(root, text='年龄').grid(row=2, column=3)
update_label_4 = ttk.Label(root, text='电话号码').grid(row=3, column=3)
update_label_5 = ttk.Label(root, text='入学日期').grid(row=4, column=3)
update_label_6 = ttk.Label(root, text='邮箱').grid(row=5, column=3)
update_entry_1 = ttk.Entry(root)
update_entry_2 = ttk.Entry(root)
update_entry_3 = ttk.Entry(root)
update_entry_4 = ttk.Entry(root)
update_entry_5 = ttk.Entry(root)
update_entry_6 = ttk.Entry(root)
update_entry_1.grid(row=0, column=4)
update_entry_2.grid(row=1, column=4)
update_entry_3.grid(row=2, column=4)
update_entry_4.grid(row=3, column=4)
update_entry_5.grid(row=4, column=4)
update_entry_6.grid(row=5, column=4)
update_button = ttk.Button(root, text='更新信息',command=lambda: update_event()).grid(row=6, column=4)
# 查找学员
search_listbox = Listbox(root, height=3)
for item in ['按学号查找', '按姓名查找', '按年龄查找']:
search_listbox.insert(END, item)
search_listbox.grid(row=0, column=6, rowspan=3)
search_label = ttk.Label(root, text='查找参数').grid(row=3, column=5)
search_entry = ttk.Entry(root)
search_entry.grid(row=3, column=6)
search_button = ttk.Button(root, text='查找', command=lambda: search_event()).grid(row=5, column=6)
delete_button = ttk.Button(root, text='删除该学员', command=lambda: delete_event()).grid(row=6, column=6)
# 排序
sort_button_1 = ttk.Button(root, text='按学号排序', command=lambda: sort_event(1)).grid(row=1, column=7)
sort_button_1 = ttk.Button(root, text='按姓名排序', command=lambda: sort_event(2)).grid(row=2, column=7)
sort_button_1 = ttk.Button(root, text='按年龄排序', command=lambda: sort_event(3)).grid(row=3, column=7)
# 信息提示框
info_label = ttk.Label(root, text="信息展示窗口", background='#66ccff', width=100, anchor='center') \
.grid(row=7, column=0, columnspan=8)
# 信息展示
Listbox(root, height=8, width=110).grid(row=8, column=0, columnspan=10)
# 选择函数, 直接用SQL进行排序
def sort_event(n):
# 连接数据库
conn_1 = Mysql_conn()
if n == 1:
# 构造查询SQL
sw = 'SELECT * FROM STUDENT ORDER BY ID'
stu_info = conn_1.select(sw)
show_listbox = Listbox(root, height=8, width=110)
for row in stu_info:
show_listbox.insert(END, row)
show_listbox.grid(row=8, column=0, columnspan=10)
messagebox.showinfo("排序", "已将学员按学号排序!")
elif n == 2:
# 构造查询SQL
sw = 'SELECT * FROM STUDENT ORDER BY NAME'
stu_info = conn_1.select(sw)
show_listbox = Listbox(root, height=8, width=110)
for row in stu_info:
show_listbox.insert(END, row)
show_listbox.grid(row=8, column=0, columnspan=10)
messagebox.showinfo("排序", "已将学员按姓名排序!")
elif n == 3:
# 构造查询SQL
sw = 'SELECT * FROM STUDENT ORDER BY AGE'
stu_info = conn_1.select(sw)
show_listbox = Listbox(root, height=8, width=110)
for row in stu_info:
show_listbox.insert(END, row)
show_listbox.grid(row=8, column=0, columnspan=10)
messagebox.showinfo("排序", "已将学员按年龄排序!")
# 关闭数据库连接
conn_1.close_conn()
# 提交学员信息
def upload_event():
i = []
# 连接数据库
conn_1 = Mysql_conn()
# root.update()
i.append(upload_entry_1.get())
i.append(upload_entry_2.get())
i.append(upload_entry_3.get())
i.append(upload_entry_4.get())
i.append(upload_entry_5.get())
# 清除输入框中的数据
upload_entry_1.delete(0, END)
upload_entry_2.delete(0, END)
upload_entry_3.delete(0, END)
upload_entry_4.delete(0, END)
upload_entry_5.delete(0, END)
# 构造SQL语句
uw = "INSERT INTO STUDENT (NAME, AGE, TEL_NUMBER, DATE, EMAIL)" \
"VALUES('%s', '%s', '%s', '%s', '%s')" %(i[0], i[1], i[2], i[3], i[4])
conn_1.insert(uw)
messagebox.showinfo("保存提示", "已保存学员信息!")
# 刷新信息区
sw = 'SELECT * FROM STUDENT ORDER BY ID'
stu_info = conn_1.select(sw)
show_listbox = Listbox(root, height=8, width=110)
for row in stu_info:
show_listbox.insert(END, row)
show_listbox.grid(row=8, column=0, columnspan=10)
# 关闭数据库连接
conn_1.close_conn()
# 更新学员信息
def update_event():
i = []
# 连接数据库
conn_1 = Mysql_conn()
i.append(update_entry_1.get())
i.append(update_entry_2.get())
i.append(update_entry_3.get())
i.append(update_entry_4.get())
i.append(update_entry_5.get())
i.append(update_entry_6.get())
# 清除输入框中的数据
update_entry_1.delete(0, END)
update_entry_2.delete(0, END)
update_entry_3.delete(0, END)
update_entry_4.delete(0, END)
update_entry_5.delete(0, END)
update_entry_6.delete(0, END)
# 构造SQL语句
uw = "UPDATE STUDENT SET NAME = '%s', AGE = '%s', TEL_NUMBER = '%s', DATE = '%s', EMAIL = '%s' WHERE " \
"ID = '%s'"% (i[1], i[2], i[3], i[4], i[5], i[0])
conn_1.update(uw)
messagebox.showinfo("更新提示", "已更新学员信息!")
# 刷新信息区
sw = 'SELECT * FROM STUDENT ORDER BY ID'
stu_info = conn_1.select(sw)
show_listbox = Listbox(root, height=8, width=110)
for row in stu_info:
show_listbox.insert(END, row)
show_listbox.grid(row=8, column=0, columnspan=10)
# 关闭数据库连接
conn_1.close_conn()
# 保存当前首位符合条件的学员的ID
cur_search_id = None
def search_event():
# 连接数据库
conn_1 = Mysql_conn()
# 构造SQL语句
sw = 'SELECT * FROM STUDENT ORDER BY ID'
stu_info = conn_1.select(sw)
# 保存当前首位符合条件的学员的ID
global cur_search_id
cur_search_id = stu_info[0][0]
for items in stu_info:
node = []
node.append(items[0])
node.append(items[1])
node.append(items[2])
node.append(items[3])
node.append(items[4])
node.append(items[5])
self.dl.add(node)
key = search_listbox.curselection()
value = search_entry.get()
# 删除搜索框中数据
search_entry.delete(0, END)
results = self.dl.find(value, key[0])
show_listbox = Listbox(root, height=8, width=110)
for row in results:
show_listbox.insert(END, row)
show_listbox.grid(row=8, column=0, columnspan=10)
# 清空链表
self.dl.release()
# 关闭数据库连接
conn_1.close_conn()
def delete_event():
# 连接数据库
conn_1 = Mysql_conn()
global cur_search_id
messagebox.showinfo("删除提示", "该学员信息已删除!")
# 从数据库中删除该学员,以保持同步
rw = "DELETE FROM STUDENT WHERE ID = '%d'" % (cur_search_id)
conn_1.delete(rw)
# 将cur_search_id 置为 None,防止误删
cur_search_id = None
# 断开数据库
conn_1.close_conn()
# 刷新数据显示
Listbox(root, height=8, width=110).grid(row=8, column=0, columnspan=10)
root = Tk()
test = GUI(root)
root.mainloop()
import tkinter as tk
from tkinter import messagebox # import this to fix messagebox error
import pickle
import webbrowser
# 创建主窗口
window = tk.Tk()
window.title('欢迎来到华南停水断电施工难毕业大学')
window.geometry('450x300')
# 添加背景图
canvas = tk.Canvas(window, height=200, width=500) # 创建画布
image_file = tk.PhotoImage(file='1.png') # 加载图片文件
image_fil = tk.PhotoImage(file='7.png') # 加载图片文件
image = canvas.create_image(170, 5, anchor='nw', image=image_file) # 将图片置于画布上
canvas.pack() # 放置画布
# 用户信息
tk.Label(window, text='账号:').place(x=110, y=150) # 创建一个`label`名为`User name: `置于坐标(120,150)
tk.Label(window, text='密码:').place(x=110, y=190)
# 账号密码输入框
var_usr_name = tk.StringVar() # 定义变量,用于输入用户名
var_usr_name.set('201830251123') # 输入用户名窗口默认显示'write your name'
entry_usr_name = tk.Entry(window, textvariable=var_usr_name) # 创建输入框
entry_usr_name.place(x=160, y=150)
var_usr_pwd = tk.StringVar()
entry_usr_pwd = tk.Entry(window, textvariable=var_usr_pwd, show='*') # `show`这个参数将输入的密码变为`***`的形式
entry_usr_pwd.place(x=160, y=190)
def run1():
webbrowser.open('https://www.scut.edu.cn/new/8995/list.htm')
def run2():
webbrowser.open('http://phtv.ifeng.com/a/20170227/44548497_0.shtml')
# 登录功能
def usr_login():
# 这两行代码就是获取用户输入的`usr_name`和`usr_pwd`
usr_name = var_usr_name.get()
usr_pwd = var_usr_pwd.get()
# 这里设置异常捕获,当我们第一次访问用户信息文件时是不存在的,所以这里设置异常捕获
try:
# 'rb'是打开文件为以二进制格式“读”,文件必须存在,否则会报错
with open('usrs_info.pickle', 'rb') as usr_file:
usrs_info = pickle.load(usr_file)
except FileNotFoundError:
# 这里就是我们在没有读取到`usr_file`的时候,程序会创建一个`usr_file`这个文件,并将管理员
# 的用户和密码写入,即用户名为`admin`密码为`admin`。
with open('usrs_info.pickle', 'wb') as usr_file:
usrs_info = {'admin': 'admin'}
pickle.dump(usrs_info, usr_file)
# 如果用户名和密码与文件中的匹配成功,则会登录成功,并跳出弹窗`how are you?`加上你的用户名
if usr_name in usrs_info:
if usr_pwd == usrs_info[usr_name]:
# 这里就是在主体窗口的window上创建一个Sign up window窗口
window_sign_up1 = tk.Toplevel(window)
window_sign_up1.geometry('400x400')
window_sign_up1.title('scut')
# 添加背景图
canvas1 = tk.Canvas(window_sign_up1, height=200, width=500) # 创建画布
image = canvas1.create_image(110, 5, anchor='nw', image=image_fil) # 将图片置于画布上
canvas1.pack() # 放置画布
scut1 = tk.Button(window_sign_up1, text='大学简介', command=run1)
scut1.place(x=135, y=190)
scut2 = tk.Button(window_sign_up1, text='教授风采', command=run2)
scut2.place(x=142, y=250)
scut3 = tk.Button(window_sign_up1, text='学生信息', command=run_nn)
scut3.place(x=142, y=310)
else:
tk.messagebox.showerror(message='Error, 密码错误,请重新尝试')
else: # 如果发现用户名不存在
is_sign_up = tk.messagebox.askyesno('Welcome',
'你还没有注册,现在要注册吗?')
# 提示需不需要注册新用户
if is_sign_up:
usr_sign_up()
# 注册功能
def usr_sign_up():
def sign_to_Mofan_Python():
# 以下三行就是获取我们注册时所输入的信息
np = new_pwd.get()
npf = new_pwd_confirm.get()
nn = new_name.get()
# 这里是打开我们记录数据的文件,将注册信息读出
with open('usrs_info.pickle', 'rb') as usr_file:
exist_usr_info = pickle.load(usr_file)
# 这里就是判断,如果两次密码输入不一致,则提示`'Error', 'Password and confirm password must be the same!'`
if np != npf:
tk.messagebox.showerror('Error', '密码前后不一致!')
# 如果用户名已经在我们的数据文件中,则提示`'Error', 'The user has already signed up!'`
elif nn in exist_usr_info:
tk.messagebox.showerror('Error', '该账号已经被别人注册,请重新注册!')
else:
exist_usr_info[nn] = np
with open('usrs_info.pickle', 'wb') as usr_file:
pickle.dump(exist_usr_info, usr_file)
tk.messagebox.showinfo('恭喜', '注册成功!')
window_sign_up.destroy()
# 这里就是在主体窗口的window上创建一个Sign up window窗口
window_sign_up = tk.Toplevel(window)
window_sign_up.geometry('350x200')
window_sign_up.title('注册窗口')
# 用户名
new_name = tk.StringVar()
new_name.set('201830251123')
tk.Label(window_sign_up, text='账号: ').place(x=10, y= 10) # 将`User name:`放置在坐标(10,10)。
entry_new_name = tk.Entry(window_sign_up, textvariable=new_name) # 设置输入姓名框
entry_new_name.place(x=150, y=10) # `entry`放置在坐标(150,10)
# 初次密码
new_pwd = tk.StringVar()
tk.Label(window_sign_up, text='密码: ').place(x=10, y=50)
entry_usr_pwd = tk.Entry(window_sign_up, textvariable=new_pwd, show='*')
entry_usr_pwd.place(x=150, y=50)
# 确认密码
new_pwd_confirm = tk.StringVar()
tk.Label(window_sign_up, text='确认密码: ').place(x=10, y=90)
entry_usr_pwd_confirm = tk.Entry(window_sign_up, textvariable=new_pwd_confirm, show='*')
entry_usr_pwd_confirm.place(x=150, y=90)
# 下面的 sign_to_Mofan_Python 我们再后面接着说
btn_comfirm_sign_up = tk.Button(window_sign_up, text='注册', command=sign_to_Mofan_Python)
btn_comfirm_sign_up.place(x=150, y=130)
# 登录和注册按钮
btn_login = tk.Button(window, text='登录', command=usr_login) # 定义一个`button`按钮,名为`Login`,触发命令为`usr_login'
btn_login.place(x=270, y=230)
btn_sign_up = tk.Button(window, text='注册', command=usr_sign_up)
btn_sign_up.place(x=120, y=230)
window.mainloop()
上述代码需要调用以下两个.py文件。
以下这段代码的.py文件名要命名为 connect_mysql
"""
数据库连接模块
__init__:初始化连接信息
insert(self, insert_words):添加字段方法
select(self, select_words):查找字段方法
update(self, update_words):更新字段方法
delete(self, delete_words):删除字段方法
"""
import pymysql
class Mysql_conn:
def __init__(self):
self.db = pymysql.connect("localhost", "root", "xxxxxxxxx", "test1")
self.cursor = self.db.cursor()
def insert(self, insert_words):
try:
# 执行sql语句
self.cursor.execute(insert_words)
# 提交到数据库执行
self.db.commit()
except:
# 如果发生错误则回滚
self.db.rollback()
def select(self, select_words):
try:
# 执行SQL语句
self.cursor.execute(select_words)
# 获取所有记录列表
results = self.cursor.fetchall()
return results
except:
print("Error: unable to fetch data")
def update(self, update_words):
try:
# 执行SQL语句
self.cursor.execute(update_words)
# 提交到数据库执行
self.db.commit()
except:
# 发生错误时回滚
self.db.rollback()
def delete(self, delete_words):
try:
# 执行SQL语句
self.cursor.execute(delete_words)
# 提交修改
self.db.commit()
except:
# 发生错误时回滚
self.db.rollback()
def close_conn(self):
self.db.close()
# 测试代码
# test1 = mysql_conn()
# 查找测试
# sw = "SELECT * FROM employee"
# test1.select(sw)
# 增添测试
# iw = """INSERT INTO EMPLOYEE(FIRSTNAME,
# LASTNAME, AGE, SEX, INCOME)
# VALUES ('Mac', 'Mohan', 20, 'M', 2000)"""
# test1.insert(iw)
# 更新测试
# uw = "UPDATE EMPLOYEE SET AGE = AGE + 1 WHERE SEX = '%s'" % ('man')
# test1.update(uw)
# 删除测试
# dw = "DELETE FROM EMPLOYEE WHERE AGE = '%d'" % (20)
# test1.delete(dw)
# test1.close_conn()
以下这段代码的.py文件名要命名为 dLink
class Node(object):
def __init__(self, data = []):
self.data = data
self.pre = None
self.next = None
class DouLink(object):
"""初始化双向链表"""
def __init__(self):
self.head = Node('head')
self.length = 1
def add(self, value):
p = self.head
new = Node(value)
while p.next:
p = p.next
p.next = new
new.pre = p
self.length += 1
def remove(self, ID):
p = self.head
while p.next:
if p.data[0] == ID:
temp = p.pre
ans = p.next
temp.next = ans
ans.pre = temp
return p
self.length -= 1
else:
p = p.next
raise AttributeError(u"can't find this element")
def release(self):
self.head = Node('head')
self.length = 1
def find(self, value, key):
results = []
p = self.head
while p.next:
# 检测下类型, 有时候会 int 和 str 比较看不出来
# print(type(key))
# print(type(value))
# print(type(p.data[2]))
if key == 0 and str(p.data[0]) == value:
results.append(p.data)
elif key == 1 and p.data[1] == value:
results.append(p.data)
elif key == 2 and str(p.data[2]) == value:
results.append(p.data)
p = p.next
print(len(results))
if len(results) > 0:
print(results)
return results
raise AttributeError(u"can't find this element")
以上程序运行后会程序一个bug, pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'localhost' ([WinError 10061] 由于目标计算机积极拒绝,无法连接。)")
如何解决,请参考链接:https://bbs.csdn.net/topics/391931225?page=1