Как использовать tkraise для другого класса фреймов в Tkinter

В настоящее время я учусь внедрять классы в свой графический интерфейс. Я знаю, как обычно использовать tkraise, но теперь это сложно.

Я получаю TypeError: login_page.widgets..sign_in() отсутствует 1 обязательный позиционный аргумент: 'self'

Я хочу, чтобы программа после того, как я вошел в систему, подняла «Основной фрейм». Я захешировал свою попытку использовать tkraise в функции Sign_in.

Может кто-нибудь объяснить, пожалуйста.

from customtkinter import *

global d_text
d_text = ''

class software(CTk):
    def __init__(self):
        super().__init__()
        self.geometry('1000x800')

        
        Main = main(self)
        Login_page = login_page(self)
        Menu = menu(Main)
        Keypad = keypad(Main)
        Sub_menu = sub_menu(Main)
        Header = header(Main)
        Right_menu = right_menu(Main)
        Admin_menu = admin_menu(Main)
        self.mainloop()

class login_page(CTkFrame):
    def __init__(self,parent):
        super().__init__(parent)
        self.configure(width=1000,height=800,fg_color='black')
        self.place(x=0,y=0)

        self.widgets()
    def widgets(self):
        
        def sign_in(self):
            if login_entryfield.get() == 'user123':
                if password_entryfield.get() == 'base12':
                    print('signed in as user')
                    #### self.Main.tkraise()
                else:
                    print('incorrect password')
                    
            else:
                print('incorrect user name')

        #widgets
        login_label = CTkLabel(self,text='Login',font = ("Arial", 20, "bold"))
        login_entryfield = CTkEntry(self, width=200)    
        password_label = CTkLabel(self,text='Password',font = ("Arial", 20, "bold"))
        password_entryfield = CTkEntry(self, width=200) 
        enter_button  = CTkButton(self,text='Login',font = ("Arial", 20, "bold"),command=sign_in)

        #layout
        login_label.place(x=300,y=100)
        login_entryfield.place(x=400,y=100)
        password_label.place(x=300,y=200)
        password_entryfield.place(x=400,y=200)
        enter_button.place(x=400,y=700)


class main(CTkFrame):
    def __init__(self,parent):
        super().__init__(parent) 
        self.configure(width=1000,height=800, fg_color='black',corner_radius=0)
        self.place(x=0,y=0)

class header(CTkFrame):
    def __init__(self,parent):
        super().__init__(parent)
        self.configure(width=1000,height=50, fg_color='green',corner_radius=0)
        self.place(x=0,y=0)

class menu(CTkFrame):
    def __init__(self,parent):
        super().__init__(parent)
        self.configure(width=450,height=450,fg_color='red',corner_radius=0)
        self.place(x=0,y=50)

class right_menu(CTkFrame):
    def __init__(self,parent):
        super().__init__(parent)
        self.configure(height=750,width=200, fg_color='purple',corner_radius=0)
        self.place(x=800,y=50)

        fv_button = CTkButton(self,text='Fruit&Veg',width=200,height=80)
        bakery_button = CTkButton(self,text='Bakery',width=200,height=80)
        Heavy_Misc_button = CTkButton(self,text='Heavy&Misc',width=200,height=80)
        bags_button = CTkButton(self,text='Recyclable Bags',width=200,height=80)
        downarrow_btn = CTkButton(self,text='↓',width=60,height=80)
        uparrow_btn = CTkButton(self,text='↑',width=60,height=80)

        fv_button.place(x=0,y=50)
        bakery_button.place(x=0,y=160)
        Heavy_Misc_button.place(x=0,y=270)
        bags_button.place(x=0,y=380)
        downarrow_btn.place(x=0,y=490)
        uparrow_btn.place(x=70,y=490)

class admin_menu(CTkFrame):
    def __init__(self,parent):
        super().__init__(parent)
        self.configure(width=1000,height=150, fg_color='green',corner_radius=0)
        self.place(x=0,y=650)

        open_btn = CTkButton(self,text='^',width=50,height=50, corner_radius=0)
        open_btn.place(x=20,y=30)

        Lock_btn = CTkButton(self,text='Lock', width=125, height=75,corner_radius=0)
        Lock_btn.place(x=100,y=30)

        logoff_btn = CTkButton(self,text='Log Off', width=125, height=75,corner_radius=0)
        logoff_btn.place(x=250,y=30)

        report_btn = CTkButton(self,text='Report Abuse', width=125, height=75,corner_radius=0)
        report_btn.place(x=400,y=30)

        item_search_btn = CTkButton(self,text='Item Search', width=125, height=75,corner_radius=0)
        item_search_btn.place(x=550,y=30)

        Return_btn = CTkButton(self,text='Returns', width=125, height=75,corner_radius=0)
        Return_btn.place(x=700,y=30)

        Funds_management = CTkButton(self,text='Funds Management', width=125, height=75,corner_radius=0)
        Funds_management.place(x=850,y=30)
        



class keypad(CTkFrame):
    def __init__(self,parent):
        super().__init__(parent)
        self.configure(width=300,height=450,fg_color='green', corner_radius=0)
        self.place(x=460,y=200)

        self.widget()   
    def widget(self):
        
        def display(var):
            global d_text
            d_text += str(var)
            lb1.configure(text=d_text)

        def clear():
            global d_text
            d_text = ''
            lb1.configure(text=d_text)
        
        def backspace():
            global d_text
            d_text = d_text[ :-1]
            lb1.configure(text=d_text)

        lb1 = CTkLabel(self,text='',width=300,fg_color='blue')

        btn1 = CTkButton(self, text=7,width=50,height=50,command=lambda:display(7))
        btn2 = CTkButton(self, text=8,width=50,height=50, command=lambda: display(8))
        btn3 = CTkButton(self, text=9,width=50,height=50, command=lambda: display(9))
        btn4 = CTkButton(self, text=4,width=50,height=50, command=lambda: display(4))
        btn5 = CTkButton(self, text=5,width=50,height=50, command=lambda: display(5))
        btn6 = CTkButton(self, text=6,width=50,height=50,command=lambda: display(6))
        btn7 = CTkButton(self, text=1,width=50,height=50, command=lambda: display(1))
        btn8 = CTkButton(self, text=2,width=50,height=50,command=lambda: display(2))
        btn9 = CTkButton(self, text=3,width=50,height=50,command=lambda: display(3))
        btn0 = CTkButton(self, text=0, width=50,height=50,command=lambda: display(0))
        decbtn = CTkButton(self,text='.',width=50,height=50,command=lambda: display('.'))
        clear_btn = CTkButton(self,text='C',width=50,height=50, command=lambda: clear())
        back_btn = CTkButton(self,text='<<',width=50,height=50, command=lambda: backspace())
        multiply_btn = CTkButton(self,text='X',width=50,height=50)
        ok_btn = CTkButton(self,text='OK',width=50,height=140)
        lb1.place(x=0,y=0)
        btn1.place(x=20,y=75)
        btn2.place(x=80,y=75)
        btn3.place(x=140,y=75)
        btn4.place(x=20,y=140)
        btn5.place(x=80,y=140)
        btn6.place(x=140,y=140)
        btn7.place(x=20,y=205)
        btn8.place(x=80,y=205)
        btn9.place(x=140,y=205)
        btn0.place(x=20,y=270)
        decbtn.place(x=80,y=270)
        clear_btn.place(x=140,y=270)
        back_btn.place(x=200,y=75)
        multiply_btn.place(x=200,y=140)
        ok_btn.place(x=200,y=205)

class sub_menu(CTkFrame):
    def __init__(self,parent):
        super().__init__(parent)
        self.configure(width=450,height=100,fg_color='yellow', corner_radius=0)
        self.place(x=0,y=450)

        self.widgets()
    def widgets(self):
        up_btn = CTkButton(self, text='↑', width=50,height=80)
        down_btn = CTkButton(self, text='↓', width=50, height=80)

        lb2 = CTkLabel(self, text='Balance due', font = ("Arial", 20, "bold"))
        lb3 = CTkLabel(self, text='0.00', font = ("Arial", 20, "bold"))
        lb4 = CTkLabel(self,text='0 items', font = ("Arial", 20, "bold"))

        up_btn.place(x=20,y=10)
        down_btn.place(x=80,y=10)
        lb2.place(x=150,y=60)
        lb3.place(x=300,y=60)
        lb4.place(x=150,y=0)

    
software()
sign_in() — это внутренняя (или вложенная) функция, а не метод класса, поэтому аргумент self не обязателен. Убери это. Также с точки зрения безопасности не сообщайте пользователю что-то вроде «неверное имя пользователя» и «неправильный пароль». Просто скажите им «неправильные учетные данные».
acw1668 19.06.2024 04:29

Спасибо. но как мне поднять основную раму?

Samurai 19.06.2024 04:34
Main — это локальная переменная внутри software.__init__(), поэтому к ней нельзя получить доступ вне этой функции. Один из способов — передать его login_page, а затем передать login_page.widgets().
acw1668 19.06.2024 04:36

как ты это проходишь?

Samurai 19.06.2024 04:39
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
4
52
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Обратите внимание, что sign_in() — внутренняя функция, поэтому аргумент self не обязателен и его можно удалить.

Кроме того, Main является локальной переменной внутри software.__init__(), поэтому к ней нельзя получить доступ вне этой функции. Вы можете передать его login_page, а затем его методу widgets():

class software(CTk):
    def __init__(self):
        ...
        Main = main(self)
        Login_page = login_page(self, Main)
        ...

class login_page(CTkFrame):
    def __init__(self, parent, main):
        ...
        self.widgets(main)

    def widgets(self, main):
        def sign_in():
            if login_entryfield.get() == 'user123':
                if password_entryfield.get() == 'base12':
                    print('signed in as user')
                    main.tkraise()
                else:
                    print('incorrect password')
            else:
                print('incorrect user name')
        ...

когда вы указываете Main вторым аргументом в 5-й строке, это выдает ошибку. login_page.__init__() принимает 2 позиционных аргумента, но было задано 3... Это потому, что Sign_in — это вложенная функция? как мне это исправить

Samurai 19.06.2024 06:10

@Samurai Ответ обновлен, чтобы исправить отсутствие аргумента parent в login_page.__init__().

acw1668 19.06.2024 07:56
Ответ принят как подходящий

Проблема

Ошибка, с которой вы столкнулись, связана с тем, что функция Sign_in определена внутри метода виджетов, что делает ее вложенной функцией. В этом контексте он не получает автоматически self в качестве первого параметра.

Чтобы исправить это, вам нужно переместить функцию Sign_in в метод класса login_page, а не внутри виджетов.

Кроме того, чтобы поднять основной фрейм после успешного входа в систему, вам необходимо передать ссылку на экземпляр основного фрейма в экземпляр login_page.

Вот исправленная версия вашего кода:


from customtkinter import *

global d_text
d_text = ''

class software(CTk):
    def __init__(self):
        super().__init__()
        self.geometry('1000x800')

        self.Main = main(self)
        self.Login_page = login_page(self, self.Main)
        self.Menu = menu(self.Main)
        self.Keypad = keypad(self.Main)
        self.Sub_menu = sub_menu(self.Main)
        self.Header = header(self.Main)
        self.Right_menu = right_menu(self.Main)
        self.Admin_menu = admin_menu(self.Main)
        self.mainloop()

class login_page(CTkFrame):
    def __init__(self, parent, main_frame):
        super().__init__(parent)
        self.main_frame = main_frame  # Store reference to the main frame
        self.configure(width=1000, height=800, fg_color='black')
        self.place(x=0, y=0)

        self.widgets()

    def sign_in(self):
        if self.login_entryfield.get() == 'user123':
            if self.password_entryfield.get() == 'base12':
                print('signed in as user')
                self.main_frame.tkraise()  # Raise the main frame
            else:
                print('incorrect password')
        else:
            print('incorrect user name')

    def widgets(self):
        # widgets
        login_label = CTkLabel(self, text='Login', font=("Arial", 20, "bold"))
        self.login_entryfield = CTkEntry(self, width=200)
        password_label = CTkLabel(self, text='Password', font=("Arial", 20, "bold"))
        self.password_entryfield = CTkEntry(self, width=200, show='*')
        enter_button = CTkButton(self, text='Login', font=("Arial", 20, "bold"), command=self.sign_in)

        # layout
        login_label.place(x=300, y=100)
        self.login_entryfield.place(x=400, y=100)
        password_label.place(x=300, y=200)
        self.password_entryfield.place(x=400, y=200)
        enter_button.place(x=400, y=700)

class main(CTkFrame):
    def __init__(self, parent):
        super().__init__(parent)
        self.configure(width=1000, height=800, fg_color='black', corner_radius=0)
        self.place(x=0, y=0)

class header(CTkFrame):
    def __init__(self, parent):
        super().__init__(parent)
        self.configure(width=1000, height=50, fg_color='green', corner_radius=0)
        self.place(x=0, y=0)

class menu(CTkFrame):
    def __init__(self, parent):
        super().__init__(parent)
        self.configure(width=450, height=450, fg_color='red', corner_radius=0)
        self.place(x=0, y=50)

class right_menu(CTkFrame):
    def __init__(self, parent):
        super().__init__(parent)
        self.configure(height=750, width=200, fg_color='purple', corner_radius=0)
        self.place(x=800, y=50)

        fv_button = CTkButton(self, text='Fruit&Veg', width=200, height=80)
        bakery_button = CTkButton(self, text='Bakery', width=200, height=80)
        Heavy_Misc_button = CTkButton(self, text='Heavy&Misc', width=200, height=80)
        bags_button = CTkButton(self, text='Recyclable Bags', width=200, height=80)
        downarrow_btn = CTkButton(self, text='↓', width=60, height=80)
        uparrow_btn = CTkButton(self, text='↑', width=60, height=80)

        fv_button.place(x=0, y=50)
        bakery_button.place(x=0, y=160)
        Heavy_Misc_button.place(x=0, y=270)
        bags_button.place(x=0, y=380)
        downarrow_btn.place(x=0, y=490)
        uparrow_btn.place(x=70, y=490)

class admin_menu(CTkFrame):
    def __init__(self, parent):
        super().__init__(parent)
        self.configure(width=1000, height=150, fg_color='green', corner_radius=0)
        self.place(x=0, y=650)

        open_btn = CTkButton(self, text='^', width=50, height=50, corner_radius=0)
        open_btn.place(x=20, y=30)

        Lock_btn = CTkButton(self, text='Lock', width=125, height=75, corner_radius=0)
        Lock_btn.place(x=100, y=30)

        logoff_btn = CTkButton(self, text='Log Off', width=125, height=75, corner_radius=0)
        logoff_btn.place(x=250, y=30)

        report_btn = CTkButton(self, text='Report Abuse', width=125, height=75, corner_radius=0)
        report_btn.place(x=400, y=30)

        item_search_btn = CTkButton(self, text='Item Search', width=125, height=75, corner_radius=0)
        item_search_btn.place(x=550, y=30)

        Return_btn = CTkButton(self, text='Returns', width=125, height=75, corner_radius=0)
        Return_btn.place(x=700, y=30)

        Funds_management = CTkButton(self, text='Funds Management', width=125, height=75, corner_radius=0)
        Funds_management.place(x=850, y=30)

class keypad(CTkFrame):
    def __init__(self, parent):
        super().__init__(parent)
        self.configure(width=300, height=450, fg_color='green', corner_radius=0)
        self.place(x=460, y=200)

        self.widget()

    def widget(self):
        def display(var):
            global d_text
            d_text += str(var)
            lb1.configure(text=d_text)

        def clear():
            global d_text
            d_text = ''
            lb1.configure(text=d_text)

        def backspace():
            global d_text
            d_text = d_text[:-1]
            lb1.configure(text=d_text)

        lb1 = CTkLabel(self, text='', width=300, fg_color='blue')

        btn1 = CTkButton(self, text=7, width=50, height=50, command=lambda: display(7))
        btn2 = CTkButton(self, text=8, width=50, height=50, command=lambda: display(8))
        btn3 = CTkButton(self, text=9, width=50, height=50, command=lambda: display(9))
        btn4 = CTkButton(self, text=4, width=50, height=50, command=lambda: display(4))
        btn5 = CTkButton(self, text=5, width=50, height=50, command=lambda: display(5))
        btn6 = CTkButton(self, text=6, width=50, height=50, command=lambda: display(6))
        btn7 = CTkButton(self, text=1, width=50, height=50, command=lambda: display(1))
        btn8 = CTkButton(self, text=2, width=50, height=50, command=lambda: display(2))
        btn9 = CTkButton(self, text=3, width=50, height=50, command=lambda: display(3))
        btn0 = CTkButton(self, text=0, width=50, height=50, command=lambda: display(0))
        decbtn = CTkButton(self, text='.', width=50, height=50, command=lambda: display('.'))
        clear_btn = CTkButton(self, text='C', width=50, height=50, command=lambda: clear())
        back_btn = CTkButton(self, text='<<', width=50, height=50, command=lambda: backspace())
        multiply_btn = CTkButton(self, text='X', width=50, height=50)
        ok_btn = CTkButton(self, text='OK', width=50, height=140)
        lb1.place(x=0, y=0)
        btn1.place(x=20, y=75)
        btn2.place(x=80, y=75)
        btn3.place(x=140, y=75)
        btn4.place(x=20, y=140)
        btn5.place(x=80, y=140)
        btn6.place(x=140, y=140)
        btn7.place(x=20, y=205)
        btn8.place(x=80, y=205)
        btn9.place(x=140, y=205)
        btn0.place(x=20, y=270)
        decbtn.place(x=80, y=270)
        clear_btn.place(x=140, y=270)
        back_btn.place(x=200, y=75)
        multiply_btn.place(x=200, y=140)
        ok_btn.place(x=200, y=205)

class sub_menu(CTkFrame):
    def __init__(self, parent):
        super().__init__(parent)
        self.configure(width=450, height=100, fg_color='yellow', corner_radius=0)
        self.place(x=0, y=450)

        self.widgets()

    def widgets(self):
        up_btn = CTkButton(self, text='↑', width=50, height=80)
        down_btn = CTkButton(self, text='↓', width=50, height=80)

        lb2 = CTkLabel(self, text='Balance due', font=("Arial", 20, "bold"))
        lb3 = CTkLabel(self, text='0.00', font=("Arial", 20, "bold"))
        lb4 = CTkLabel(self, text='0 items', font=("Arial", 20, "bold"))

        up_btn.place(x=20, y=10)
        down_btn.place(x=80, y=10)
        lb2.place(x=150, y=60)
        lb3.place(x=300, y=60)
        lb4.place(x=150, y=0)

software()

Некоторые дополнительные предложения

Другие вопросы по теме