如何调用 class A 方法 inside class B 方法 in Python
How to call class A method inside class B method in Python
当我想在 class B 方法中调用 class A 方法时,我目前遇到了一个问题。代码 运行 没问题。但是,问题发生在 ImageProcessing.py 中的第 73 行,其中 MainApplication.signup() 要求参数。此函数是为返回注册页面而构建的。我不确定这样编码是否正确。请帮我。我将不胜感激。
*这是Display.py
import tkinter as tk
from tkinter import *
from PIL import ImageTk, Image
import os
import ImageProcessing
class MainApplication:
def __init__(self,master): # parent, *args, **kwargs):
self.master = master
self.frame = tk.Frame(self.master)
# Resize image
self.open_image = Image.open('images/log_icon.png')
self.resized_image = self.open_image.resize((170, 170), Image.ANTIALIAS)
# Define image
self.img = ImageTk.PhotoImage(self.resized_image)
self.bg1 = ImageTk.PhotoImage(Image.open('images/darkblue.png'))
self.lock = ImageTk.PhotoImage(Image.open('Icon/lock.ico'))
self.loginBtn = ImageTk.PhotoImage(Image.open('images/login-button.png'))
# Create labels and buttons
self.my_label = Label(master, image=self.bg1)
self.my_label.place(x=0, y=0, relwidth=1, relheight=1)
self.log_head = Label(master, image=self.img, bg="#1f1a30")
self.log_head.place(x=115, y=10)
self.lock_label = Label(master, image=self.lock, bg="#39304d")
self.lock_label.place(x=50, y=200, height=35, width=40)
self.username = Entry(master, font=("arial", 13), bg="#39304d", fg="white", borderwidth=0)
self.username.place(x=90, y=200, width=250, height=35)
self.login_btn = Button(master, image=self.loginBtn, borderwidth=0, bg="#1f1a30", activebackground="#1f1a30", command=self.login)
self.login_btn.place(x=35, y=300)
self.signup_label = Label(master, text="Don't have an account?", bg="#1f1a30", font=("times new roman", 10),
fg="white")
self.signup_label.place(x=110, y=380)
self.signup_btn = Button(master, text="Sign Up", borderwidth=0, bg="#1f1a30", font=("times new roman", 10, "underline"),
fg="#0df6e3", activebackground="#1f1a30", command=self.signup)
self.signup_btn.place(x=240, y=380)
self.forget_btn = Button(master, text="Forgot Your Password?", borderwidth=0, bg="#1f1a30",
font=("times new roman", 10),
fg="#0df6e3", activebackground="#1f1a30")
self.forget_btn.place(x=132, y=410)
def signup(self):
def open(filename):
os.chdir("C:\Python Projects\PyFYP") # file path
os.system('python ' + filename) # run the python command on cmd to execute both windows
self.master.destroy()
open("Registration.py")
def login(self):
pass
def main_login():
App = tk.Tk()
App.title("Login")
App.iconbitmap('C:/Python Projects/PyFYP/Icon/snake2.ico')
App.resizable(False, False)
# Put TK Window screen to center
app_width = 390
app_height = 500
screen_width = App.winfo_screenwidth()
screen_height = App.winfo_screenheight()
sys_width = (screen_width / 2) - (app_width / 2)
sys_height = (screen_height / 2) - (app_height / 2)
App.geometry(f'{app_width}x{app_height}+{int(sys_width)}+{int(sys_height)}')
MainApplication(App)
App.mainloop()
if __name__ == "__main__":
main_login()
*这是ImageProcessing.py
import tkinter as tk
from tkinter import *
from tkinter import ttk, filedialog
from tkinter.filedialog import askopenfile
from PIL import ImageTk, Image
import cv2
import numpy as np
from tkinter import messagebox
import time
import Display
class ProcessImage():
def __init__(self, master): # parent, *args, **kwargs):
self.master = master
self.frame = tk.Frame(self.master)
self.bg = ImageTk.PhotoImage(Image.open('images/neon.png'))
self.Upload_Btn_img = ImageTk.PhotoImage(Image.open('images/upload_btn.png'))
self.proceed_Btn_img = ImageTk.PhotoImage(Image.open('images/proceed_btn.png'))
self.cancel_Btn_img = ImageTk.PhotoImage(Image.open('images/cancel_btn.png'))
self.reset_Btn_img = ImageTk.PhotoImage(Image.open('images/reset_btn.png'))
# Labels and Buttons
self.Img_process_background = tk.Label(master, image=self.bg)
self.Img_process_background.place(x=0, y=0, relwidth=1, relheight=1)
# OpenCV window name
self.windowName = "Selected Image"
# Attributes for setting coordinates
self.coordinate = np.zeros((3, 2), int)
self.counter = 0
self.file_path_name = "" # Uploaded image's file path
# Upload Image label
self.uploadImg_label = Label(master, text="Please upload your preference image here.", bg="#1f1a30", font=("arial", 12, "bold"), fg="white")
self.uploadImg_label.place(x=50, y=50)
self.uploadImg_note = Label(master, text="* Only jpg, jpeg, png, are allowed.", bg="#1f1a30", font=("arial", 8, "bold"), fg="grey")
self.uploadImg_note.place(x=50, y=75)
self.img_resize_note = Label(master, text="* Image will be resize to 900x500.", bg="#1f1a30",font=("arial", 8, "bold"), fg="grey")
self.img_resize_note.place(x=50, y=100)
self.txt_uploadImg = Entry(master, font=("arial", 10), bg="#39304d", fg="white", borderwidth=0)
self.txt_uploadImg.place(x=50, y=125, width=350, height=20)
# Create Buttons
self.upload_btn = tk.Button(master, image=self.Upload_Btn_img, command=self.Browsing, borderwidth=0, bg="#1f1a30",activebackground="#1f1a30")
self.upload_btn.place(x=170, y=175, width=120)
self.reset_Btn = Button(master, command=self.reset_it, image=self.reset_Btn_img, borderwidth=0, bg="#1f1a30",activebackground="#1f1a30")
self.reset_Btn.place(x=80, y=250, width=120)
self.cancel_btn = Button(master, command=self.cancel_it, image=self.cancel_Btn_img, borderwidth=0, bg="#1f1a30",activebackground="#1f1a30")
self.cancel_btn.place(x=260, y=250, width=120)
self.proceed_btn = Button(master, image=self.proceed_Btn_img, borderwidth=0, bg="#1f1a30",activebackground="#1f1a30", command=self.SetCoordinates)
self.proceed_btn.place(x=170, y=400, width=120)
def reset_it(self):
self.counter = 0
self.txt_uploadImg.delete(0, "end")
self.file_path_name = ""
messagebox.showinfo(title="Success", message="Points have been reset")
def cancel_it(self):
# Initialize variables
self.master.destroy()
self.counter = 0
self.file_path_name = ""
MainApplication.signup() # Return to sign up/register page
def SetCoordinates(self):
try:
self.read_img = cv2.imread(self.file_path_name) # read image
self.resized_img = cv2.resize(self.read_img, (900,500))
while True:
cv2.namedWindow(self.windowName)
cv2.imshow(self.windowName, self.resized_img)
cv2.setMouseCallback(self.windowName, self.PassPoints)
cv2.waitKey(1)
if self.counter == 3:
time.sleep(0.5)
messagebox.showinfo(title="Success", message="Points were marked successfully")
cv2.destroyWindow(self.windowName)
break
except:
messagebox.showerror(title="Error message", message="Image not found")
cv2.destroyWindow(self.windowName)
def PassPoints(self, event, x, y, flags, params):
global counter
if event == cv2.EVENT_LBUTTONDOWN:
self.coordinate[self.counter] = x, y
colorsB = self.resized_img[y, x, 0]
colorsG = self.resized_img[y, x, 1]
colorsR = self.resized_img[y, x, 2]
self.counter += 1
print("x= " + str(x) + " y= " + str(y))
print('Red: ' + str(colorsR) + ' ' + 'Green: ' + str(colorsG) + ' ' + 'Blue: ' + str(colorsB))
def Browsing(self):
img_file = filedialog.askopenfile(mode='r', filetypes=[('JPEG', '*.jpeg'), ('JPEG', '*.jpg'), ('PNG', '*.png')])
global file_path_name
def setImageNameInput(self, text):
self.txt_uploadImg.delete(0, "end")
self.txt_uploadImg.insert(0, text)
# img_file.name: the .name used to get the file path of the uploaded image
if img_file:
setImageNameInput(self,img_file.name)
self.file_path_name = img_file.name
def main_image_process():
Imageprocess_page = tk.Tk()
Imageprocess_page.title("Image processing")
Imageprocess_page.iconbitmap('C:/Python Projects/PyFYP/Icon/snake2.ico')
Imageprocess_page.resizable(False, False)
app_width = 900
app_height = 500
screen_width = Imageprocess_page.winfo_screenwidth()
screen_height = Imageprocess_page.winfo_screenheight()
sys_width = (screen_width / 2) - (app_width / 2)
sys_height = (screen_height / 2) - (app_height / 2)
Imageprocess_page.geometry(f'{app_width}x{app_height}+{int(sys_width)}+{int(sys_height)}')
ProcessImage(Imageprocess_page)
Imageprocess_page.mainloop()
if __name__ == "__main__":
main_image_process()
*这是错误
TypeError: signup() 缺少 1 个必需的位置参数:'self'
您不能调用该方法,因为它不是静态/class方法,而是实例/对象[=的方法class MainApplication.
的 45=]
这意味着 cancel_it
方法的参数 self
期望 class MainApplication
的实例正常运行,但是通过调用 MainApplication.cancel_it()
它接收class 而不是 作为参数并且 因此抛出异常 .
您可以轻松调用它,只需将 reference 传递给 Mainapplication-instance 给您的 cancel_it方法.
假设:
self.master
在ProcessImage
classe的__init__
方法是对Main-Application实例的引用,解决方案看起来像这样:
def cancel_it(self):
# Initialize variables
self.master.destroy()
self.counter = 0
self.file_path_name = ""
self.master.signup() # Return to sign up/register page
否则,method-adjustment 可能看起来像这样:
def cancel_it(self, main_application):
# Initialize variables
self.master.destroy()
self.counter = 0
self.file_path_name = ""
main_application.signup() # Return to sign up/register page
其中 main_application
是对 MainApplication 的引用,它必须作为参数传递。
如果后一种情况应该成立 - 请记住,您还必须调整负责调用该函数的按钮的 command
,以便它实际传递参数 main_application
.
当我想在 class B 方法中调用 class A 方法时,我目前遇到了一个问题。代码 运行 没问题。但是,问题发生在 ImageProcessing.py 中的第 73 行,其中 MainApplication.signup() 要求参数。此函数是为返回注册页面而构建的。我不确定这样编码是否正确。请帮我。我将不胜感激。
*这是Display.py
import tkinter as tk
from tkinter import *
from PIL import ImageTk, Image
import os
import ImageProcessing
class MainApplication:
def __init__(self,master): # parent, *args, **kwargs):
self.master = master
self.frame = tk.Frame(self.master)
# Resize image
self.open_image = Image.open('images/log_icon.png')
self.resized_image = self.open_image.resize((170, 170), Image.ANTIALIAS)
# Define image
self.img = ImageTk.PhotoImage(self.resized_image)
self.bg1 = ImageTk.PhotoImage(Image.open('images/darkblue.png'))
self.lock = ImageTk.PhotoImage(Image.open('Icon/lock.ico'))
self.loginBtn = ImageTk.PhotoImage(Image.open('images/login-button.png'))
# Create labels and buttons
self.my_label = Label(master, image=self.bg1)
self.my_label.place(x=0, y=0, relwidth=1, relheight=1)
self.log_head = Label(master, image=self.img, bg="#1f1a30")
self.log_head.place(x=115, y=10)
self.lock_label = Label(master, image=self.lock, bg="#39304d")
self.lock_label.place(x=50, y=200, height=35, width=40)
self.username = Entry(master, font=("arial", 13), bg="#39304d", fg="white", borderwidth=0)
self.username.place(x=90, y=200, width=250, height=35)
self.login_btn = Button(master, image=self.loginBtn, borderwidth=0, bg="#1f1a30", activebackground="#1f1a30", command=self.login)
self.login_btn.place(x=35, y=300)
self.signup_label = Label(master, text="Don't have an account?", bg="#1f1a30", font=("times new roman", 10),
fg="white")
self.signup_label.place(x=110, y=380)
self.signup_btn = Button(master, text="Sign Up", borderwidth=0, bg="#1f1a30", font=("times new roman", 10, "underline"),
fg="#0df6e3", activebackground="#1f1a30", command=self.signup)
self.signup_btn.place(x=240, y=380)
self.forget_btn = Button(master, text="Forgot Your Password?", borderwidth=0, bg="#1f1a30",
font=("times new roman", 10),
fg="#0df6e3", activebackground="#1f1a30")
self.forget_btn.place(x=132, y=410)
def signup(self):
def open(filename):
os.chdir("C:\Python Projects\PyFYP") # file path
os.system('python ' + filename) # run the python command on cmd to execute both windows
self.master.destroy()
open("Registration.py")
def login(self):
pass
def main_login():
App = tk.Tk()
App.title("Login")
App.iconbitmap('C:/Python Projects/PyFYP/Icon/snake2.ico')
App.resizable(False, False)
# Put TK Window screen to center
app_width = 390
app_height = 500
screen_width = App.winfo_screenwidth()
screen_height = App.winfo_screenheight()
sys_width = (screen_width / 2) - (app_width / 2)
sys_height = (screen_height / 2) - (app_height / 2)
App.geometry(f'{app_width}x{app_height}+{int(sys_width)}+{int(sys_height)}')
MainApplication(App)
App.mainloop()
if __name__ == "__main__":
main_login()
*这是ImageProcessing.py
import tkinter as tk
from tkinter import *
from tkinter import ttk, filedialog
from tkinter.filedialog import askopenfile
from PIL import ImageTk, Image
import cv2
import numpy as np
from tkinter import messagebox
import time
import Display
class ProcessImage():
def __init__(self, master): # parent, *args, **kwargs):
self.master = master
self.frame = tk.Frame(self.master)
self.bg = ImageTk.PhotoImage(Image.open('images/neon.png'))
self.Upload_Btn_img = ImageTk.PhotoImage(Image.open('images/upload_btn.png'))
self.proceed_Btn_img = ImageTk.PhotoImage(Image.open('images/proceed_btn.png'))
self.cancel_Btn_img = ImageTk.PhotoImage(Image.open('images/cancel_btn.png'))
self.reset_Btn_img = ImageTk.PhotoImage(Image.open('images/reset_btn.png'))
# Labels and Buttons
self.Img_process_background = tk.Label(master, image=self.bg)
self.Img_process_background.place(x=0, y=0, relwidth=1, relheight=1)
# OpenCV window name
self.windowName = "Selected Image"
# Attributes for setting coordinates
self.coordinate = np.zeros((3, 2), int)
self.counter = 0
self.file_path_name = "" # Uploaded image's file path
# Upload Image label
self.uploadImg_label = Label(master, text="Please upload your preference image here.", bg="#1f1a30", font=("arial", 12, "bold"), fg="white")
self.uploadImg_label.place(x=50, y=50)
self.uploadImg_note = Label(master, text="* Only jpg, jpeg, png, are allowed.", bg="#1f1a30", font=("arial", 8, "bold"), fg="grey")
self.uploadImg_note.place(x=50, y=75)
self.img_resize_note = Label(master, text="* Image will be resize to 900x500.", bg="#1f1a30",font=("arial", 8, "bold"), fg="grey")
self.img_resize_note.place(x=50, y=100)
self.txt_uploadImg = Entry(master, font=("arial", 10), bg="#39304d", fg="white", borderwidth=0)
self.txt_uploadImg.place(x=50, y=125, width=350, height=20)
# Create Buttons
self.upload_btn = tk.Button(master, image=self.Upload_Btn_img, command=self.Browsing, borderwidth=0, bg="#1f1a30",activebackground="#1f1a30")
self.upload_btn.place(x=170, y=175, width=120)
self.reset_Btn = Button(master, command=self.reset_it, image=self.reset_Btn_img, borderwidth=0, bg="#1f1a30",activebackground="#1f1a30")
self.reset_Btn.place(x=80, y=250, width=120)
self.cancel_btn = Button(master, command=self.cancel_it, image=self.cancel_Btn_img, borderwidth=0, bg="#1f1a30",activebackground="#1f1a30")
self.cancel_btn.place(x=260, y=250, width=120)
self.proceed_btn = Button(master, image=self.proceed_Btn_img, borderwidth=0, bg="#1f1a30",activebackground="#1f1a30", command=self.SetCoordinates)
self.proceed_btn.place(x=170, y=400, width=120)
def reset_it(self):
self.counter = 0
self.txt_uploadImg.delete(0, "end")
self.file_path_name = ""
messagebox.showinfo(title="Success", message="Points have been reset")
def cancel_it(self):
# Initialize variables
self.master.destroy()
self.counter = 0
self.file_path_name = ""
MainApplication.signup() # Return to sign up/register page
def SetCoordinates(self):
try:
self.read_img = cv2.imread(self.file_path_name) # read image
self.resized_img = cv2.resize(self.read_img, (900,500))
while True:
cv2.namedWindow(self.windowName)
cv2.imshow(self.windowName, self.resized_img)
cv2.setMouseCallback(self.windowName, self.PassPoints)
cv2.waitKey(1)
if self.counter == 3:
time.sleep(0.5)
messagebox.showinfo(title="Success", message="Points were marked successfully")
cv2.destroyWindow(self.windowName)
break
except:
messagebox.showerror(title="Error message", message="Image not found")
cv2.destroyWindow(self.windowName)
def PassPoints(self, event, x, y, flags, params):
global counter
if event == cv2.EVENT_LBUTTONDOWN:
self.coordinate[self.counter] = x, y
colorsB = self.resized_img[y, x, 0]
colorsG = self.resized_img[y, x, 1]
colorsR = self.resized_img[y, x, 2]
self.counter += 1
print("x= " + str(x) + " y= " + str(y))
print('Red: ' + str(colorsR) + ' ' + 'Green: ' + str(colorsG) + ' ' + 'Blue: ' + str(colorsB))
def Browsing(self):
img_file = filedialog.askopenfile(mode='r', filetypes=[('JPEG', '*.jpeg'), ('JPEG', '*.jpg'), ('PNG', '*.png')])
global file_path_name
def setImageNameInput(self, text):
self.txt_uploadImg.delete(0, "end")
self.txt_uploadImg.insert(0, text)
# img_file.name: the .name used to get the file path of the uploaded image
if img_file:
setImageNameInput(self,img_file.name)
self.file_path_name = img_file.name
def main_image_process():
Imageprocess_page = tk.Tk()
Imageprocess_page.title("Image processing")
Imageprocess_page.iconbitmap('C:/Python Projects/PyFYP/Icon/snake2.ico')
Imageprocess_page.resizable(False, False)
app_width = 900
app_height = 500
screen_width = Imageprocess_page.winfo_screenwidth()
screen_height = Imageprocess_page.winfo_screenheight()
sys_width = (screen_width / 2) - (app_width / 2)
sys_height = (screen_height / 2) - (app_height / 2)
Imageprocess_page.geometry(f'{app_width}x{app_height}+{int(sys_width)}+{int(sys_height)}')
ProcessImage(Imageprocess_page)
Imageprocess_page.mainloop()
if __name__ == "__main__":
main_image_process()
*这是错误 TypeError: signup() 缺少 1 个必需的位置参数:'self'
您不能调用该方法,因为它不是静态/class方法,而是实例/对象[=的方法class MainApplication.
的 45=]这意味着 cancel_it
方法的参数 self
期望 class MainApplication
的实例正常运行,但是通过调用 MainApplication.cancel_it()
它接收class 而不是 作为参数并且 因此抛出异常 .
您可以轻松调用它,只需将 reference 传递给 Mainapplication-instance 给您的 cancel_it方法.
假设:
self.master
在ProcessImage
classe的__init__
方法是对Main-Application实例的引用,解决方案看起来像这样:
def cancel_it(self):
# Initialize variables
self.master.destroy()
self.counter = 0
self.file_path_name = ""
self.master.signup() # Return to sign up/register page
否则,method-adjustment 可能看起来像这样:
def cancel_it(self, main_application):
# Initialize variables
self.master.destroy()
self.counter = 0
self.file_path_name = ""
main_application.signup() # Return to sign up/register page
其中 main_application
是对 MainApplication 的引用,它必须作为参数传递。
如果后一种情况应该成立 - 请记住,您还必须调整负责调用该函数的按钮的 command
,以便它实际传递参数 main_application
.