Извлечение значения из поля ввода Tkinter

#python #tkinter

#python #tkinter

Вопрос:

Я пытаюсь заставить Tkinter вернуть значение из поля ввода, но, похоже, у меня не получается заставить его работать.

Это моя первая попытка попробовать Tkinter, s

 Exception in Tkinter callback
Traceback (most recent call last):
  File "C:UsersrikAppDataLocalProgramsPythonPython38-32libtkinter__init__.py", line 1883, in __call__
    return self.func(*args)
  File "n:regnskabAfregningRIKUdviklingguiapp2.py", line 43, in step_1
    periode_2 = get_period(self)
NameError: name 'get_period' is not defined
 
 import tkinter as tk
from tkinter import ttk

class Mainframe(tk.Tk):
    def __init__(self, *args, **kvargs):
        super().__init__(*args, **kvargs)


        self.title("app")

        UserInputFrame(self).grid(row=1, column=0)
        ControlsFrame(self).grid(row=2, column=0)
        ButtonFrame(self).grid(row=3, column=0)


class UserInputFrame(ttk.Frame):
    def __init__(self, container):
        super().__init__(container)

        self.user_input_year = tk.StringVar(value="2021")

        label_entry_year = ttk.Label(self, text="Year")
        self.entry_year = ttk.Entry(self, textvariable=self.user_input_year)

        label_entry_year.grid(row=2, column=0, sticky="W", padx=10, pady=5)
        self.entry_year.grid(row=2, column=1, sticky="EW")

    def get_period(self):
        print(self.entry_year.get())



class ControlsFrame(ttk.Frame):
    def __init__(self, container):
        super().__init__(container)

        step_1_button = ttk.Button(self, text="Step 1", command=self.step_1)


        step_1_button.grid(row=10, column=0, sticky="EW")

    def step_1(self):
        periode_2 = get_period(self)
        print("step 1")



class ButtonFrame(ttk.Frame):
    def __init__(self, container):
        super().__init__(container)

        quit_button = ttk.Button(self, text="Quit", command=quit)
        quit_button.grid(row=4, column=1, sticky="EW")


    def quit(self):
        app.destroy


app = Mainframe()
app.mainloop()

 

Комментарии:

1. вы должны учиться OOP . get_period это не отдельная функция, а функция внутри класса UserInputFrame , поэтому вам нужно будет получить экземпляр UserInputFrame , отправить его в качестве аргумента ControlsFrame и затем использовать instance_of_control_frame.get_period() Вы не можете получить доступ к функции одного класса из другого класса.

Ответ №1:

Вы должны изучить ООП 🙂

get_period() это не отдельная функция, а функция внутри класса UserInputFrame , и вы пытаетесь получить к ней доступ в классе ControlsFrame . Таким образом, вы не можете получить доступ к функции для одного класса в другом классе.

Вам нужно будет получить экземпляр UserInputFrame ,

     user_input_frame = UserInputFrame(self)
    user_input_frame.grid(row=1, column=0)
 

отправьте его в качестве аргумента в ControlsFrame

     ControlsFrame(self, user_input_frame).grid(row=2, column=0)
 

храните его в переменной класса

 class ControlsFrame(ttk.Frame):
    def __init__(self, container, user_input_frame):
        super().__init__(container)

        self.user_input_frame = user_input_frame
 

и тогда вы сможете им воспользоваться

 def step_1(self):
    self.user_input_frame.get_period()  # without `self` in `get_period()`
 

ИЛИ лучший метод

Вы должны ссылаться UserInputFrame на переменную класса в Mainframe

 self.user_input_frame = UserInputFrame(self)
self.user_input_frame.grid(row=1, column=0)
 

и тогда другие объекты (созданные в Mainframe ) могут получить доступ Mainframe (который является его paret / master), используя self.master , а затем они могут получить доступ к элементам, Mainframe подобным self.master.userinputframe

 periode_2 = self.master.user_input_frame.get_period() # without `self` in `get_period()`
 

 import tkinter as tk
from tkinter import ttk

class Mainframe(tk.Tk):
    def __init__(self, *args, **kvargs):
        super().__init__(*args, **kvargs)

        self.title("app")

        self.user_input_frame = UserInputFrame(self)
        self.user_input_frame.grid(row=1, column=0)

        ControlsFrame(self).grid(row=2, column=0)
        ButtonFrame(self).grid(row=3, column=0)


class UserInputFrame(ttk.Frame):
    def __init__(self, container):
        super().__init__(container)

        self.user_input_year = tk.StringVar(value="2021")

        label_entry_year = ttk.Label(self, text="Year")
        self.entry_year = ttk.Entry(self, textvariable=self.user_input_year)

        label_entry_year.grid(row=2, column=0, sticky="W", padx=10, pady=5)
        self.entry_year.grid(row=2, column=1, sticky="EW")

    def get_period(self):
        #print(self.entry_year.get())
        return self.entry_year.get()



class ControlsFrame(ttk.Frame):
    def __init__(self, container):
        super().__init__(container)

        step_1_button = ttk.Button(self, text="Step 1", command=self.step_1)
        step_1_button.grid(row=10, column=0, sticky="EW")

    def step_1(self):
        # `self.master` gives access to parent object which here is `Masterframe` (because you used `Masterframe` as `self` when you created `ControlsFrame(self)`
        periode_2 = self.master.user_input_frame.get_period() # without `self` in `get_period()`
        print("step 1")



class ButtonFrame(ttk.Frame):
    def __init__(self, container):
        super().__init__(container)

        quit_button = ttk.Button(self, text="Quit", command=self.quit)
        quit_button.grid(row=4, column=1, sticky="EW")

    def quit(self):
        app.destroy()


app = Mainframe()
app.mainloop()
 

Кстати: в ButtonFrame ты забыл self. в command=self.quit и () в app.destroy()


РЕДАКТИРОВАТЬ: как заметил @acw1668, функция get_period() не возвращает значение из записи — она только печатает его — поэтому ей нужно return

     def get_period(self):
        return self.entry_year.get()
 

Комментарии:

1. Пожалуйста, обратите внимание, что get_period() возврат None . Измените его на def get_period(self): return self.entry_year.get() .

2. @acw1668 хороший момент 🙂 Я добавил его в ответ

3. большое спасибо — заставил его работать со вторым методом. Почему вы считаете, что это превосходит первое?

4. вторая версия универсальна — все классы имеют доступ к user_input_frame . Таким же образом вы можете получить доступ self.master.user_input_frame ButtonFrame в. Если вы добавите другой виджет в главное окно, у него также будет доступ self.master.user_input_frame . И аналогичным образом вы можете установить self.control_frame = ControlsFrame(...) , и другие виджеты будут иметь доступ к control_frame использованию self.master.control_frame .