带有tkinter GUI的Python GPA计算器程序

带有tkinter GUI的Python GPA计算器程序,python,tkinter,Python,Tkinter,我正在尝试使用tkinter在python中创建一个GPA计算器。我正在使用python 3.1。 以下是我到目前为止为GUI所做的工作 root = Tk() root.title('GPA Calculator') #create frames self.column_headers = Frame(root) self.class1_frame = Frame(root) self.class2_frame = Frame(root)

我正在尝试使用tkinter在python中创建一个GPA计算器。我正在使用python 3.1。 以下是我到目前为止为GUI所做的工作

    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等

我做了很多研究,虽然我对它有一点接触,但我不知道如何将它整合到我的GUI中


任何帮助都将不胜感激,提前感谢。

因此,我完全同意jon_darkstar关于不硬编码课程的观点。这看起来像是它自己的类的主要候选者(在编程概念的意义上)

但是,要用下拉菜单(称为*OptionMenu*s)替换输入框,您需要执行以下操作:

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 = ["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()
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()
Course.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()
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) 这并不完美,我做了更多的调整——但如果您打算通过创建一个类的每个课程和实例来清理代码,这会让您朝着正确的方向前进


(感谢对新编辑的投票)

因此,我完全同意jon_darkstar关于不硬编码课程的观点。这看起来像是它自己的类的主要候选者(在编程概念的意义上)

但是,要用下拉菜单(称为*OptionMenu*s)替换输入框,您需要执行以下操作:

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 = ["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()
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()
Course.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()
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) 这并不完美,我做了更多的调整——但如果您打算通过创建一个类的每个课程和实例来清理代码,这会让您朝着正确的方向前进


(感谢您为新编辑投票)

我建议不要硬编码4门课程(我说课程是为了避免混淆)。您可以将它们保存在一个集合中,为课程及其相关GUI对象创建类,等等,这是我正在进行的一个项目。我建议不要硬编码4门课程(我说课程是为了避免混淆)。您可以将它们保存在一个集合中,为课程及其相关GUI对象创建类,等等,这是我正在进行的一个项目。谢谢,我现在有了下拉框,是的,我最初打算在这个项目中使用类(python类),只是想先完成布局。谢谢你开始上课。我还打算这样做,以便我可以存储一个学期(4个班)的信息,并使用它来计算他们的累计GPA,这是他们迄今为止所有学期的组合。我如何利用您为我启动的类来实现这一点?我将使用回调来运行一个函数,该函数将重新计算GPA并更新GPA标签的值。我该如何实现这一点?我对如何让下拉菜单选择设置该类的等级有点困惑。谢谢,我现在有了下拉框,是的,我最初打算在这个项目中使用类(python类),只是想先完成布局。谢谢你开始上课。我还打算这样做,以便我可以存储一个学期(4个班)的信息,并使用它来计算他们的累计GPA,这是他们迄今为止所有学期的组合。我如何利用您为我启动的类来实现这一点?我将使用回调来运行一个函数,该函数将重新计算GPA并更新GPA标签的值。我该如何实现这一点?我对如何让下拉菜单选择设置该课程的分数有点困惑。