简体   繁体   English

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

[英]Trying to Return an Input from a Dropdown Menu to a Variable in Tkinter

I'm writing one of my first programs, and I can't figure out how to fix this issue. 我正在编写我的第一个程序,但我不知道如何解决此问题。 I started learning Python like a week ago and am still very new to Tkinter and OOP in general. 我像一个星期前开始学习Python,但总体上对Tkinter和OOP还是很陌生。 I got this script (D&D NPC Generator) working without using OOP, but I wanted to see how to do it with OOP since that's how most people seem to prefer using Tkinter. 我使该脚本(D&D NPC生成器)在不使用OOP的情况下工作,但是我想看看如何在OOP上进行操作,因为这是大多数人似乎更喜欢使用Tkinter的方式。

Here's the code for the Input window: 这是“输入”窗口的代码:

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()

And it's returning: 它正在返回:

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

I have no idea what's going wrong. 我不知道怎么回事。 My goal with this GUI window is to have the user type in a name for the NPC and then select an option from a drowbown menu for what kind of ideal the user wants the NPC to have. 我使用此GUI窗口的目标是让用户输入NPC的名称,然后从长袍菜单中选择一个选项,以使用户希望NPC具有什么样的理想状态。 A fix and explanation of what I did wrong would be very helpful, thank you. 修复和解释我做错了的事情将非常有帮助,谢谢。

You've declared ideal_selection as a local variable and not a class instance variable. 您已将ideal_selection声明为局部变量,而不是类实例变量。 Therefore, calling self.ideal_selection.get() will fail as there is no self to reference. 因此,调用self.ideal_selection.get()将失败,因为没有要引用的self

You need to change the declaration from: ideal_selection = StringVar() to: this.ideal_selection = StringVar() and change all other references over to this.ideal_selection . 您需要将声明从: ideal_selection = StringVar()更改为: this.ideal_selection = StringVar() ,并将所有其他引用更改为this.ideal_selection

Note that you have done this for everything else ( self.name_entry ) ... 请注意,您已对其他所有内容( self.name_entry )完成了此self.name_entry ...

Afterword: 后记:

I'd like to discourage you from your use of global here. 我想劝阻您不要在这里使用global When you have tkinter running under OOP principles, you can return values from your class back to the calling script. 当您在OOP原则下运行tkinter时,可以将类中的值返回给调用脚本。

(Note also eventually I would recommend not using from tkinter import * ). (请注意,最终我还是建议不要使用from tkinter import * )。

Have a look at what happens if your code is amended to: 看看将您的代码修改为以下内容会发生什么:

#! /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)  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM