用tkinter GUI构建的Python GPA计算器程序

0 投票
1 回答
4887 浏览
提问于 2025-04-16 17:02

我正在尝试用Python和tkinter创建一个GPA计算器。我使用的是Python 3.1。

    root = Tk()
    root.title('GPA Calculator')

    #create frames
    self.column_headers = Frame(root)
    self.class1_frame = Frame(root)
    self.class2_frame = Frame(root)
    self.class3_frame = Frame(root)
    self.class4_frame = Frame(root)
    self.enterClasses_frame= Frame(root)
    self.deposit_frame = Frame(root)


    self.column_header = Label(self.column_headers, \
    text = 'Credit Hours                        Grade',fg = 'black')
    self.column_header.pack(side = 'left')

    self.class1label = Label(self.class1_frame, \
        text = 'Class 1:', fg = 'black')
    self.class1label.pack(side = 'left')
    self.creditHours1 = Entry(self.class1_frame)
    self.creditHours1.pack(side = 'left')
    self.grade1 = Entry(self.class1_frame)
    self.grade1.pack(side = 'left')

    self.class2label = Label(self.class2_frame, \
        text = 'Class 2:', fg = 'black')
    self.class2label.pack(side = 'left')
    self.creditHours2 = Entry(self.class2_frame)
    self.creditHours2.pack(side = 'left')
    self.grade2 = Entry(self.class2_frame)
    self.grade2.pack(side = 'left')


    self.class3label = Label(self.class3_frame, \
    text = 'Class 3:', fg = 'black')
    self.class3label.pack(side = 'left')
    self.creditHours3 = Entry(self.class3_frame)
    self.creditHours3.pack(side = 'left')
    self.grade3 = Entry(self.class3_frame)
    self.grade3.pack(side = 'left')


    self.class4label = Label(self.class4_frame, \
    text = 'Class 4:', fg = 'black')
    self.class4label.pack(side = 'left')
    self.creditHours4 = Entry(self.class4_frame)
    self.creditHours4.pack(side = 'left')
    self.grade4 = Entry(self.class4_frame)
    self.grade4.pack(side = 'left')


    self.enterClasses = Button(self.enterClasses_frame, text = 'Submit Classes',bg = 'blue',\
        fg = 'white')
    self.enterClasses.pack(side = 'left')



    #pack frames
    self.column_headers.pack()
    self.class1_frame.pack()
    self.class2_frame.pack()
    self.class3_frame.pack()
    self.class4_frame.pack()
    self.enterClasses_frame.pack()


    root.mainloop()

我想为成绩设置一个下拉框,或者类似的东西,让用户可以选择他们的成绩,比如A、A-、B+、B等等。

我做了很多研究,虽然我对这个有一点了解,但我完全不知道怎么把它放进我的界面里。

任何帮助都会非常感谢,提前谢谢大家。

1 个回答

3

我完全同意jon_darkstar的看法,不应该把课程写死在代码里。这看起来很适合做成一个独立的类(在编程的概念上)。

不过,如果你想把输入框换成下拉菜单(叫做*OptionMenu*),你可以这样做:

self.class1label = Label(self.class1_frame, \
    text = 'Class 1:', fg = 'black')
self.class1label.pack(side = 'left')
self.creditHours1 = Entry(self.class1_frame)
self.creditHours1.pack(side = 'left')
#self.grade1 = Entry(self.class1_frame)
#self.grade1.pack(side = 'left')
self.grade1 = StringVar(root)
self.grade1.set("  ")
self.g1opt = OptionMenu(self.class1_frame, self.grade1, *GRADES)
self.g1opt.pack(side = 'right')

注意,我把你的输入框代码注释掉了,并在下面添加了我自己的代码。

另外,我在引用GRADES之前先定义了它:

GRADES = ["A","B","C","D","F"]

不过你可以根据自己的需要修改它(比如加上加减分等)。

你还应该考虑创建一个回调函数,这个函数会在用户每次改变下拉菜单的值时被调用(或者打开下拉菜单并重新选择当前选项时)。你可以先创建一个回调函数,比如:

def dd_cb(selected):
    print("Dropdown Callback: ", selected)

然后把上面部分倒数第二行修改成每个课程类似下面的样子:

self.g1opt = OptionMenu(self.class1_frame, self.grade1, *GRADES, command=dd_cb)

我需要指出的是,这样做你无法知道是哪个下拉菜单被改变了,所以这也是为什么把这些单独的行做成类的实例的另一个原因。如果你这样做,你可以写成:

self.g1opt = OptionMenu(self.class1_frame, self.grade1, *GRADES, command=self.dd_cb)

而不是这样。

我有点激动了...

开始引导你把每个课程变成一个类的实例。

gpacalc.py

from tkinter import *
import Course

class App(object):

    def __init__(self):
        root = Tk()
        root.title('GPA Calculator')

        self.column_headers = Frame(root)
        self.enterClasses_frame= Frame(root)
        self.deposit_frame = Frame(root)

        self.column_header = Label(self.column_headers, \
        text = 'Credit Hours                                   Grade',fg = 'black')
        self.column_header.pack(side = 'left')

        self.enterClasses = Button(self.enterClasses_frame, text='Submit Classes', bg='blue',\
            fg='white')
        self.enterClasses.pack(side = 'left')

        # Define the number of Courses -- eventually, you might want to make this user-editable
        NUM_COURSES = 4

        # Create Courses
        self.courses = list()
        for i in range(1, NUM_COURSES+1):
            self.courses.append(Course.Course(root, i))


        # Pack Frames
        self.column_headers.pack()
        for c in self.courses:
            c.pack()
        self.enterClasses_frame.pack()


        root.mainloop()

a = App()

Course.py

import tkinter

GRADES = ["A","B","C","D","F"]

class Course(object):


    def __init__(self, root, course_id):
        # Store Course ID
        self.course_id = course_id
        # Create Frame
        self.frame = tkinter.Frame(root)
        # Create Label
        self.label = tkinter.Label(self.frame, text = ('Class %d:' % course_id), fg = 'black')
        self.label.pack(side = 'left')
        # Create Credit Hours Entry
        self.hours = tkinter.Entry(self.frame)
        self.hours.pack(side = 'left')
        # Create Grade Dropdown
        self.grade = tkinter.StringVar(root)
        self.grade.set("  ")
        self.gopt = tkinter.OptionMenu(self.frame, self.grade, *GRADES, command=self.dd_cb)
        self.gopt.pack(side = 'left')

    def dd_cb(self, selected):
        print("Course %d Dropdown Event: %s" % (self.course_id, selected))

    def pack(self):
        self.frame.pack()

这里有几点需要注意:

1) 现在,回调函数能够知道是哪个下拉菜单被改变了。试试看,你应该能得到类似下面的输出:

Course 1 Dropdown Event: A
Course 2 Dropdown Event: B
Course 3 Dropdown Event: C

2) 你可以通过编辑NUM_COURSES变量来改变课程的数量。

3) 这不是完美的,我还会做更多的调整——但这能让你朝着把每个课程做成类的实例的方向前进。

(如果你喜欢这个新编辑,请给个赞)

撰写回答