[英]Python Tkinter GUI Frame: How to call a class method from inside a function of another class?
I am trying to create a login script for my program. 我正在尝试为我的程序创建一个登录脚本。 I was able to write a basic script to test out my Login Frame but I now what to be able to access another Frame after I essentially login. 我能够编写一个基本脚本来测试我的登录框架,但现在我基本上登录后可以访问另一个框架。
Here is part of my script: 这是我脚本的一部分:
#!/usr/bin/python
from tkinter import *
from tkinter import ttk
import tkinter as tk
import tkinter.messagebox as tm
Large_Font = ("Verdana", 18)
Small_Font = ("Verdana", 12)
class ATM(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "ATM Simulator")
container = tk.Frame(self)
container.pack(side = "top", fill ="both", expand =True)
container.grid_rowconfigure(100, weight=1)
container.grid_columnconfigure(100, weight=1)
#Create Frame Library and use For Loop to switch between frames
self.frames = {}
for i in (LogIn, WelcomePage, Checking, Savings, Transfer):
frame = i(container, self)
self.frames[i] = frame
frame.grid(row= 100, column = 100, sticky= "nsew")
self.show_frame(LogIn)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class LogIn(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
global act_num_entry
global pin_num_entry
label = Label(self, text = "Login Using Account and PIN Numbers", font=Small_Font)
label.pack(pady=50, padx=50)
act_num_label = Label(self, text="Account Number")
act_num_entry = Entry(self)
pin_num_label = Label(self, text="PIN Number")
pin_num_entry = Entry(self, show="*")
act_num_label.pack(pady=5, padx=5)
pin_num_label.pack(pady=5, padx=5)
act_num_entry.pack(pady=5, padx=5)
pin_num_entry.pack(pady=5, padx=5)
logBTN = ttk.Button(self, text="Enter",
command =self.log_check)
logBTN.pack()
quitButton = ttk.Button(self, text = "End Transaction", command = quit)
quitButton.pack()
def log_check(self):
#default test pin and account numbers
act_num=1234567
pin_num=1234
#This Try/Except handles the non-integer values being entered
try:
actNum = int(act_num_entry.get())
pinNum = int(pin_num_entry.get())
except:
tm.showerror("Login Error", "Invalid Entry")
pass
if actNum == act_num and pinNum == pin_num:
#Message Window only used to to prove my log_check function works
tm.showinfo("ATM Login", "Login Successful")
'''Insert script to open the WelcomePage(tk.Frame) method'''
elif actNum != act_num:
tm.showerror("Login Error", "Invalid Account Number")
elif pinNum != pin_num:
tm.showerror("Login Error", "Invalid PIN Number")
else:
tm.showerror("Login Error", "Invalid Entry")
class WelcomePage(tk.Frame):
#Welcome Page Window
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = Label(self, text = "Welcome to the ATM Simulator", font = Large_Font)
label.pack(pady=100, padx=100)
checkButton = ttk.Button(self, text = "Checking Account",
command = lambda: controller.show_frame(Checking))
checkButton.pack()
saveButton = ttk.Button(self, text = "Savings Account",
command = lambda: controller.show_frame(Savings))
saveButton.pack()
transButton = ttk.Button(self, text = "Transfer Funds",
command = lambda: controller.show_frame(Transfer))
transButton.pack()
quitButton = ttk.Button(self, text = "End Transaction", command = self.client_exit)
quitButton.pack()
def client_exit(self):
exit()
So I want to call my WelcomePage(tk.Frame)
method from inside my if actNum == act_num and pinNum == pin_num:
function so I can essentially login to my program. 所以我想从我的if actNum == act_num and pinNum == pin_num:
函数内部调用我的WelcomePage(tk.Frame)
方法,这样我基本上可以登录到我的程序。 I tried to access the WelcomePage(tk.Frame)
using my show_frame function but I was not able to because I understand that the function is apart of the ATM(tk.Tk)
class not LogIn(tk.Frame)
. 我尝试使用show_frame函数访问WelcomePage(tk.Frame)
但由于无法理解该函数是ATM(tk.Tk)
类而不是LogIn(tk.Frame)
而无法LogIn(tk.Frame)
。 Is this possible to accomplish the way I want to or am I going to have to write another login script to accomplish this? 这是否有可能实现我想要的方式,或者我将不得不编写另一个登录脚本来实现此目的?
show_frame
is a method on the controller. show_frame
是控制器上的方法。 You simply need to save a reference to the controller, and call it from anywhere. 您只需要保存对控制器的引用,然后从任何地方调用它即可。 This is the entire purpose of the controller class - to control access to the other windows. 这是控制器类的全部目的- 控制对其他窗口的访问。
The first step is to modify your classes to save a reference to the controller: 第一步是修改您的类以保存对控制器的引用:
class Login(tk.Frame):
def __init__(self, parent, controller):
self.controller = controller
...
class WelcomePage(tk.Frame):
def __init__(self, parent, controller):
self.controller = controller
...
Now, you can call show_frame
wherever you want: 现在,您可以在任何需要的地方调用show_frame
:
if actNum == act_num and pinNum == pin_num:
...
self.controller.show_frame(WelcomePage)
...
For more information on the controller see this answer: https://stackoverflow.com/a/32865334/7432 有关控制器的更多信息,请参见以下答案: https : //stackoverflow.com/a/32865334/7432
Inside LogIn
use parent
to get access to ATM
where you have self.frames[WelcomePage]
在LogIn
内部,使用parent
可以访问具有self.frames[WelcomePage]
ATM
self.frames[WelcomePage]
self.parent.frames[WelcomePage].some_function()
Probably you will have to add in LogIn.__init__
line 可能您需要在LogIn.__init__
行中添加
self.parent = parent
EDIT: 编辑:
because LogIn
is inside container
which is inside ATM
you have use 因为LogIn
位于您使用过的ATM
内的container
中
self.parent.master.show_frame(WelcomePage)
Or you can use 或者你可以使用
self.master.master.show_frame(WelcomePage)
and then you don't need to add self.parent = parent
然后您不需要添加self.parent = parent
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.