美文网首页
(三)Python GUI实战:统计学生人数

(三)Python GUI实战:统计学生人数

作者: 小雨Coding | 来源:发表于2020-08-17 17:38 被阅读0次

    在开始这个项目之前,我们先了解一下类变量的基础知识:

    一、类变量

    1. 实例变量和实例函数

    静态属性 ==> 实例变量/成员变量
    动态属性 ==> 实例函数(方法)/成员函数(方法)
    每一份实例都有自己独立的一份数据;
    对于公共的数据(对每个对象没有差异的数据),我们把它定义成实例变量是不合理的。我们只需要存储一份, 应该把它定义成类变量,所有的对象后期调用的时候直接调用类变量就可以了。这样可以提高运行速度、节约对象实例化的内存资源。

    2. 类变量

    类变量一般位于类名称的下面,构造函数的上面;

    class Person:
        count = 0   # 类变量
        def __init__(self,name,age):
            self.name = name    # 成员变量
            self.age = age
            Person.count += 1
        def say_hello(self):    # 成员函数
            print("大家好,我是"+self.name+",今年"+self.age+"岁!")
    
    if __name__ == '__main__':
        peter = Person("peter","20")
        peter.say_hello()
    
        # 想通过一个变量来记录这个类被实例化多少次
        alice = Person("alice", "22")
        alice.say_hello()
        print(Person.count)
    

    类变量只存储一份,存储在类空间中,在每个对象的空间中不需要存储类变量

    3. 类变量的访问

    在类中访问类变量: 类名.类变量名称
    在对象中访问类变量:类名.类变量名称或者对象名.类变量名称
    推荐:如果访问类变量,最好还是通过类名.类变量名称来进行访问。

    4. 对象变量访问的顺序

    如果类变量与实例变量同名,使用对象名.类变量名访问,优先访问的是实例变量。
    原则:变量通过对象名.变量名的方式访问时,优先在当前对象中查找有没有该变量名,如果没有则去类空间中查找该变量名。

    二、GUI 界面搭建

    我们搭建一个可以统计学生人数的窗体,包括男生人数和女生人数:

    from tkinter import *
    from tkinter.ttk import *
    import os
    
    class StudentGUI(Tk):
    
        def __init__(self):
            super().__init__()
            self.title("计算学生人数")
            self.geometry("602x520+300+100")
            self.resizable(0,0)
            self["bg"] = "whitesmoke"
            # 加载具体的界面控件
            self.setuo_UI()
    
        def setuo_UI(self):
            # 设置Style
            self.style01 = Style()
            self.style01.configure("title.TLabel",font=("微软雅黑",25,"bold"),foreground = "navy")
            self.style01.configure("TLabel", font=("微软雅黑", 18, "bold"))
            # 设置Banner
            self.Top_image = PhotoImage(file = "."+os.sep+"img"+os.sep+"stu_detail_banner.png")
            self.Label_image = Label(self,image = self.Top_image)
            self.Label_image.place(x=1,y=1)
            self.Label_title = Label(self,text = "统计学生信息",style = "title.TLabel")
            self.Label_title.place(x = 380,y = 20 )
            # 设置统计区域
            self.Label_total = Label(self,text = "总人数:")
            self.Label_total.place(x=20,y=95)
            self.var_total = StringVar()
            self.Entry_total = Entry(self,state=DISABLED,textvariable = self.var_total,width =8,font=("微软雅黑", 18, "bold"))
            self.Entry_total.place(x=90,y=90)
            self.Label_man = Label(self, text="男生人数:")
            self.Label_man.place(x=210, y=95)
            self.var_man = StringVar()
            self.Entry_man = Entry(self,state=DISABLED,textvariable = self.var_man,width=8,font=("微软雅黑", 18, "bold"))
            self.Entry_man.place(x=300, y=90)
            self.Label_woman = Label(self, text="女生人数:")
            self.Label_woman.place(x=410, y=95)
            self.vat_woman = StringVar()
            self.Entry_woman = Entry(self,state=DISABLED,textvariable = self.vat_woman,width=8,font=("微软雅黑", 18, "bold"))
            self.Entry_woman.place(x=500, y=90)
            # 加载表格
            self.Tree = Treeview(self,columns=("sno","name","gender","birthday","mobile"),show="headings",height = 20)
            self.Tree.column("sno",width=120,anchor="center")
            self.Tree.column("name",width=90,anchor="center")
            self.Tree.column("gender",width=90,anchor="center")
            self.Tree.column("birthday",width=130,anchor="center")
            self.Tree.column("mobile",width=150,anchor="center")
            self.Tree.heading("sno",text="学号")
            self.Tree.heading("name", text="姓名")
            self.Tree.heading("gender", text="性别")
            self.Tree.heading("birthday", text="出生日期")
            self.Tree.heading("mobile", text="手机号码")
            self.Tree.place(x=10,y=130)
    
    if __name__ == '__main__':
        this_gui = StudentGUI()
        this_gui.mainloop()
    
    显示效果:
    屏幕快照 2020-08-16 下午9.49.42.png

    三、实现数据统计的功能

    前面的界面我们已经搭建好啦,现在我们要写一个student模块来实现数据统计的功能。
    学生列表、男生人数、女生人数,我们将其作为类变量存储在Student类中,我们定义一个load_student函数用来读取文件中的学生信息,并实现男生女生人数的统计功能

    def load_student(self):
        try:
            # 读取文件
            with open(file = Student.file_path,mode="r",encoding="UTF-8") as fd:
                # 逐行读取
                current_line = fd.readline()
                while current_line:
                    student_info = current_line.split(",")
                    # 判断男女
                    if student_info[2] == "男":
                        Student.male_number += 1
                    else:
                        Student.female_number += 1
                    # 把当前学生添加到类变量student_list[]中
                    Student.student_list.append(student_info)
                    # 读取下一行
                    current_line = fd.readline()
        except:
            showinfo("系统消息","读取消息出现异常!")
    

    为了防止每次实例化这个类的时候,类变量收到干扰;我们定义一个机制:在Student类的构造方法中,在调用load_student方法前先判断一下,如果类变量student_list数据为空,则需要导入,否则不导入数据。

    def __init__(self):
        if len(Student.student_list) == 0:
            self.load_student()
    

    四、完成GUI界面数据的加载

    现在我们把GUI与后台的功能做一个整合,这里我们定义一个控制程序start.py,作为程序的入口;

    import studentgui
    
    if __name__ == '__main__':
        this_window = studentgui.StudentGUI()
        this_window.mainloop()
    

    现在已经可以从程序入口打开GUI了,但是还没有显示人数、表格中的数据也没有显示。所以我们需要在studentgui中再添加一个load_student_info函数,将功能函数获取到结果加载到GUI界面中。这里主要做两件事:

    1. 填充人数

    先实例化操作学生的类,

    this_student = student.Student()
    

    没有实例变量,实例化还有什么用?实际上,如果不实例化的话,Student类中的数据是无法导入到StudentGUI中来用的。
    实例化完成后,在StudentGUI中直接给显示学生人数的变量设置值即可:

    self.var_man.set(student.Student.male_number)
    self.var_woman.set(student.Student.female_number)
    self.var_total.set(int(student.Student.male_number)+int(student.Student.female_number))
    
    2. 导入数据到表格

    给GUI界面的TreeView表格填充数据,填充之前先将TreeView清空:

    for i in self.Tree.get_children():
        self.Tree.delete(i)
    

    然后判断传递过来的student_list里是否有数据,如果没有数据则弹出警示框,有数据则使用insert方法逐行插入数据:

    if len(student.Student.student_list) == 0:
        showinfo("系统消息","没有数据加载")
    else:
        # 获取student.Student.student_list的数据
        list_student = student.Student.student_list
        # 遍历list_student逐条插入
        for index in range(len(list_student)):
            self.Tree.insert("",index,values=(
                list_student[index][0],list_student[index][1],list_student[index][2],
                list_student[index][3],list_student[index][4]))
    

    至此,我们的项目已经基本完成了

    显示效果
    4.gif

    相关文章

      网友评论

          本文标题:(三)Python GUI实战:统计学生人数

          本文链接:https://www.haomeiwen.com/subject/uktxjktx.html