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

10-07 10:11