Попытка вернуть ввод из выпадающего меню в переменную в Tkinter - PullRequest
0 голосов
/ 26 июня 2018

Я пишу одну из моих первых программ и не могу понять, как решить эту проблему.Я начал изучать Python, как неделю назад, и все еще очень плохо знаком с Tkinter и OOP в целом.Я получил этот скрипт (D & D NPC Generator), работающий без использования ООП, но я хотел посмотреть, как это сделать с ООП, поскольку именно так большинство людей предпочитают использовать 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, а затем выбрал опцию в меню drowbown для того, какой идеал пользователь хочет иметь NPC.Спасибо за исправление и объяснение того, что я сделал неправильно.

1 Ответ

0 голосов
/ 26 июня 2018

Вы объявили ideal_selection как локальную переменную, а не переменную экземпляра класса.Следовательно, вызов self.ideal_selection.get() не удастся, так как нет ссылки self.

Вам нужно изменить объявление с: ideal_selection = StringVar() на: this.ideal_selection = StringVar() и изменить все остальные ссылки на this.ideal_selection.

Обратите внимание, что вы сделали это для всего остального (self.name_entry) ...

Послесловие:

Я хотел бы отговорить вас от использования global здесь.Если у вас 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)  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...