【问题标题】:Python tkinter button widget executing function outside of parent Toplevel widget classPython tkinter 按钮小部件在父 Toplevel 小部件类之外执行功能
【发布时间】:2018-04-13 04:21:48
【问题描述】:

根据一些 youtube 示例开始编写 tkinter 程序:

import os
import tkinter as tk
from tkinter import ttk
import sys


def login():
    username = user_entry.get()
    pw = password_entry.get()
    if (user, pw) in Users:
        if (username, pw) == ('Admin', 'AdminPassword'):
            '''LOAD FIRST TIME ADMIN LOGON???????'''
            login_window.destroy()
        else:
            '''LOAD NORMAL USER or NORMAL ADMIN WINDOW'''
    else:
        warn.config(text="Invalid Username or Password", fg="black", bg='red')




class main_window(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.title('Pilot Flight and Duty Tracker')
        self.geometry('1000x700+250+50')
        self.resizable(width = False, height = False)
        self._frame = None
        Login_Window = Login(self)

        Users = [('Admin','AdminPassword')]

    def switch_frame(self, frame_name):
        new_frame = frame_name(self)
        if self._frame is not None:
            self._frame.destroy()
        self._frame = new_frame
        self._frame.pack()




class Login(tk.Toplevel):
    def __init__(self, master, *args, **kwargs):
        tk.Toplevel.__init__(self, master, *args, **kwargs)
        self.title('User Login')
        self.resizable(width = False, height = False)
        self.attributes('-topmost', True)
        self.geometry('230x200+625+275')
        self.title('User Login')
        self.grab_set()
        self.transient(master)
        userlabel = tk.Label(self, text="Employee ID:", font='arial 10 bold')
        userlabel.place(x=25, y=5)
        user_entry = tk.Entry(self, relief='groove', width=25, font='arial 10', bd=1)
        user_entry.place(x=25, y=30)
        passwordlabel = tk.Label(self, text="Password:", font='arial 10 bold')
        passwordlabel.place(x=25, y=70)
        password_entry = tk.Entry(self, relief='groove', width=25, font='arial 10', show="*", bd=1)
        password_entry.place(x=25, y=95)
        warn = tk.Label(self, font='arial 10 bold')
        warn.place(x=25, y=135)
        button = tk.Button(self, text="Login", relief='groove', width=12, font='arial 15 bold', justify='center', command=login)
        button.place(x=37, y=140)


run = main_window()
run.mainloop()

在我需要 Toplevel 小部件的“按钮”来调用“登录”功能之前工作正常。我知道我可能可以在函数中添加一些东西来解决所有这些问题,但是,似乎无论我将函数放置在哪里,或者它的缩进级别,我总是在回调时遇到错误。如果我将函数放在顶级小部件的 init 和其余按钮、标签等之间,它们不会使用顶层小部件的其余部分进行初始化。那么,有没有办法让这个函数在我定义的 Toplevel 小部件类中工作?

【问题讨论】:

    标签: python function tkinter window toplevel


    【解决方案1】:

    将你的变量作为类变量添加到__init__,这样它就可以在类的其他方法中访问 -

    import os
    import Tkinter as tk
    import ttk
    import sys
    
    
    class main_window(tk.Tk):
        def __init__(self, *args, **kwargs):
            tk.Tk.__init__(self, *args, **kwargs)
            self.title('Pilot Flight and Duty Tracker')
            self.geometry('1000x700+250+50')
            self.resizable(width = False, height = False)
            self._frame = None
            Login_Window = Login(self)
    
            Users = [('Admin','AdminPassword')]
    
        def switch_frame(self, frame_name):
            new_frame = frame_name(self)
            if self._frame is not None:
                self._frame.destroy()
            self._frame = new_frame
            self._frame.pack()
    
    
    
    
    class Login(tk.Toplevel):
        def __init__(self, master, *args, **kwargs):
            tk.Toplevel.__init__(self, master, *args, **kwargs)
            self.title('User Login')
            self.resizable(width = False, height = False)
            self.attributes('-topmost', True)
            self.geometry('230x200+625+275')
            self.title('User Login')
            self.grab_set()
            self.transient(master)
            userlabel = tk.Label(self, text="Employee ID:", font='arial 10 bold')
            userlabel.place(x=25, y=5)
            self.user_entry = tk.Entry(self, relief='groove', width=25, font='arial 10', bd=1)
            self.user_entry.place(x=25, y=30)
            passwordlabel = tk.Label(self, text="Password:", font='arial 10 bold')
            passwordlabel.place(x=25, y=70)
            self.password_entry = tk.Entry(self, relief='groove', width=25, font='arial 10', show="*", bd=1)
            self.password_entry.place(x=25, y=95)
            self.warn = tk.Label(self, font='arial 10 bold')
            self.warn.place(x=25, y=135)
            button = tk.Button(self, text="Login", relief='groove', width=12, font='arial 15 bold', justify='center', command=self.login)
            button.place(x=37, y=140)
    
        def login(self):
            self.username = self.user_entry.get()
            self.pw = self.password_entry.get()
            if (self.username, self.pw) in Users:
                if (self.username, self.pw) == ('Admin', 'AdminPassword'):
                    '''LOAD FIRST TIME ADMIN LOGON???????'''
                    self.destroy()
                else:
                    '''LOAD NORMAL USER or NORMAL ADMIN WINDOW'''
            else:
                self.warn.config(text="Invalid Username or Password", fg="black", bg='red')
    
    
    run = main_window()
    run.mainloop()
    

    【讨论】:

    • 非常感谢!没有意识到我需要他们拥有自我。在前面...也不记得我需要(self)登录功能。
    • 一个后续问题-在登录功能的第一个if语句下(我现在删除了第二个),我添加了'self.warn.config(text ='登录成功!') , bg='绿色', justify='中心'。我添加了一个时间延迟,这样你就可以在标签被破坏之前看到它的变化。我没有收到任何错误,但它并没有改变标签小部件的外观,我不知道为什么......
    • time.sleep() 使线程在呈现警告之前进入睡眠状态。为此使用“之后”。将 self.destroy 替换为 'self.after(2000, self.destroy)' 以添加 2 秒延迟
    猜你喜欢
    • 2022-06-18
    • 1970-01-01
    • 1970-01-01
    • 2016-03-24
    • 1970-01-01
    • 2019-01-04
    • 1970-01-01
    • 1970-01-01
    • 2014-12-17
    相关资源
    最近更新 更多