Вызов textvariable из функции внутри класса Python 3 ткинтер - PullRequest
0 голосов
/ 04 апреля 2020

Благодарен за любую помощь в моем вопросе.

Я использую Python 3 с tkinter, где я настроил несколько страниц, однако я пытаюсь вызвать конкретную c текстовую переменную, которая находится в классе в рамках определения и интереса, возможно ли это сделать так, как я построил свой сценарий.

Это довольно большой сценарий, поэтому я не хочу вставлять здесь весь код, надеюсь, этого будет достаточно.

Обычно этот класс называется POIIN (tk.frame), и я пытаюсь вызвать

class POPage(tk.Frame):
def __init__(self, parent, controller):
    tk.Frame.__init__(self, parent)

    self.entryboxes()

def entryboxes(self):
    # Entry boxes + variables
    global voucher
    voucher = IntVar()
    entry_box3 = tk.Entry(self, textvariable=voucher, width=32, bg="lightgreen")
    entry_box3.place(x=435, y=151)

Я пытаюсь вызвать переменную text, выполнив следующие действия вне класса:

def do_mssql():
try:
    if int(POPage.entryboxes(voucher).get()) > int(maxN):
        voucherchktext()
    elif int(voucher.get()) < int(minN):
        voucherchktext()

    else:
        sql()
except:
    vouchermissing()

Однако кажется, что он вызывает IntVar (), и я не получаю никакого сообщения об ошибке (совершенно новое для Python). В принципе, я могу извлечь ваучер из другого класса (страницы), просто выполнив int (voucher.get ()). Я мог бы, конечно, переименовать текстовую переменную и назвать ее так (что я не против), но было бы здорово, если бы был какой-то способ обойти это.

Отлично для любой помощи!

BR

1 Ответ

1 голос
/ 05 апреля 2020

Спасибо за размещение всего вашего кода на pastebin. Просматривая ваш код, я вижу, что ни один из ваших классов на самом деле не становится владельцем созданных ими виджетов tkinter. Другими словами, они не имеют переменных экземпляра. Я бы предложил радикальный редизайн и избавление от всех global переменных и объектов - в этом случае это серьезный запах кода и предполагает наличие недостатка в вашем дизайне - и это хорошо, вы все-таки сказали, что вы были новичком , Я вижу и много хорошего в вашем коде! Не быть односторонним ...

По сути, я рекомендую следующее изменение: каждый класс фреймов должен стать владельцем созданных ими виджетов. Это включает в себя такие вещи, как tk.Label s, tk.Button s, tk.Entry s и tk.IntVar s и другие.

Основное преимущество, которое это дает, заключается в том, что любой экземпляр вашего класса фрейма будет иметь свой собственный tk.IntVar (или любая другая переменная виджета ввода, например tk.StringVar), которой он не должен делиться ни с одним из других классов (вы назвали это textvariable). Это имеет смысл, если подумать: каждый виджет tk.Entry связан с одним переменным объектом, который отслеживает введенные пользователем данные для этого виджета ввода - если вы создаете только одну глобальную переменную записи и делитесь ею со всеми виджетами ввода во всех фреймы, вы можете легко потерять введенные пользователем данные - на самом деле нет причин делать это.

Попробуйте запустить / поиграться со следующим фрагментом кода:

import tkinter as tk


class MyFrame(tk.Frame):

    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)

        self.label = tk.Label(self, text="Some Text")
        self.label.pack()

        self.entry_var = tk.IntVar()
        self.entry = tk.Entry(self, textvariable=self.entry_var, width=32)
        self.entry.pack()

        self.button = tk.Button(self, text="Print this frame's 'entry_var'", command=lambda: print(self.entry_var.get()))
        self.button.pack()


class Application(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.title("Title")
        self.geometry("256x256")
        self.resizable(width=False, height=False)

        self.frames = []

        for frame in MyFrame(), MyFrame():
            self.frames.append(frame)
            frame.pack()

def main():

    application = Application()
    application.mainloop()

    return 0


if __name__ == "__main__":
    import sys
    sys.exit(main())

У вас есть главный Application (вы называете это Ghost в вашем примере), который имеет несколько кадров (в моем примере только один класс кадров, но Application имеет два экземпляра этого класса кадров). Каждый экземпляр фрейма имеет виджет записи и уникальный, совершенно отдельный и отдельный объект соответствующей переменной записи. У фреймов нет причин использовать один и тот же объект входной переменной. Создание виджетов и переменных объектов-экземпляров переменных экземпляров их классов должно полностью исключить использование переменных global.

В моем примере, если бы мне нужно было получить доступ к значениям в виджетах входа извне классов - как в функции main, например, вы сказали бы application.frames[0].entry_var.get(), чтобы получить значение в виджете ввода первого кадра.

...