尝试将输入从下拉菜单返回到Tkinter中的变量

时间:2018-06-26 01:37:29

标签: python tkinter

我正在写我的第一个程序,但我不知道如何解决此问题。我像一个星期前开始学习Python,但总体上对Tkinter和OOP还是很陌生。我使该脚本(D&D NPC生成器)在不使用OOP的情况下工作,但是我想看看如何在OOP上进行操作,因为多数人似乎更喜欢使用Tkinter。

这是“输入”窗口的代码:

class Input:

    def __init__(self, master):

        ideals = ["Good", "Evil",
                  "Lawful", "Chaotic",
                  "Neutral", "Other"]

        ideal_selection = StringVar()
        ideal_selection.set(ideals[0])

        self.name_label = Label(master, text="NPC Name: ")
        self.name_entry = Entry(master)

        self.ideal_label = Label(master, text="Ideal Type: ")
        self.ideal_entry = OptionMenu(master, ideal_selection, *ideals)

        self.submit_button = Button(text="Submit", command=self.close_window)

        self.name_label.grid(row=0, column=0)
        self.name_entry.grid(row=0, column=1)

        self.ideal_label.grid(row=1, column=0)
        self.submit_button.grid(columnspan=2, row=3, column=0)

        self.ideal_entry.grid(row=1, column=1)

    def close_window(self):
        global name
        global ideal_type
        name = self.name_entry.get()
        ideal_type = self.ideal_selection.get()
        self.master.destroy()

它正在返回:

AttributeError: 'Input' object has no attribute 'ideal_selection'

我不知道怎么了。我使用此GUI窗口的目标是让用户输入NPC的名称,然后从长袍菜单中选择一个选项,以使用户希望NPC具有什么样的理想状态。修复和解释我做错了的事情将非常有帮助,谢谢。

1 个答案:

答案 0 :(得分:0)

您已将ideal_selection声明为局部变量,而不是类实例变量。 因此,调用self.ideal_selection.get()会失败,因为没有self可供引用。

您需要将声明从ideal_selection = StringVar()更改为:this.ideal_selection = StringVar(),并将所有其他引用更改为this.ideal_selection

请注意,您已经为其他所有操作(self.name_entry

后记:

在这里,我不鼓励您使用global。当您按照OOP原则运行tkinter时,可以将类中的值返回给调用脚本。

(请注意,最终我还是建议不要使用from tkinter import *)。

看看将您的代码修改为以下内容会发生什么情况:

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import tkinter as tk
import sys

class Input(tk.Frame):

    def __init__(self, parent):

        tk.Frame.__init__(self, parent)
        self.parent = parent

        ideals = ["Good", "Evil",
                  "Lawful", "Chaotic",
                  "Neutral", "Other"]

        self.ideal_selection = tk.StringVar()
        self.ideal_selection.set(ideals[0])

        self.name_label = tk.Label(root, text="NPC Name: ")
        self.name_entry = tk.Entry(root)

        self.ideal_label = tk.Label(root, text="Ideal Type: ")
        self.ideal_entry = tk.OptionMenu(root, self.ideal_selection, *ideals)

        self.submit_button = tk.Button(text="Submit", command=self.close_window)

        self.name_label.grid(row=0, column=0)
        self.name_entry.grid(row=0, column=1)

        self.ideal_label.grid(row=1, column=0)
        self.submit_button.grid(columnspan=2, row=3, column=0)

        self.ideal_entry.grid(row=1, column=1)

    def close_window(self):
        #global name
        #global ideal_type
        self.name = self.name_entry.get()
        self.ideal_type = self.ideal_selection.get()
        #self.destroy()
        self.quit()

if __name__ == '__main__':
    root = tk.Tk()
    root.geometry("600x400+300+300")
    app = Input(root)
    root.mainloop()
    # Note the returned variables here
    # They must be assigned to external variables
    # for continued use
    returned_name = app.name
    returned_ideal = app.ideal_type
    print("Your name is: " + returned_name)
    print("Your ideal is: " + returned_ideal)
    # Should only need root.destroy() to close down tkinter
    # But need to handle user cancelling the form instead
    try:
        root.destroy()
    except:
        sys.exit(1)