按钮按下后的结果没有出现在预期的区域中
本项目包含3 个文件
main.py
from customtkinter import *
import tkinter as tk
from tkinter import ttk
from include.frame_select import FrameSelect
from include.frame_main import FrameMain
window = CTk()
window.geometry("600x800+100+100")
window.resizable(1,1)
frame_select = FrameSelect(window)
frame_select.grid(row = 0, column = 0, sticky = N + W)
frame_main = FrameMain(window)
frame_main.grid(row = 0, column = 1, sticky = N + W)
window.mainloop()
frame_select.py(在目录 include)
import tkinter as tk
from tkinter import ttk
from customtkinter import *
from include.frame_main import FrameMain
class FrameSelect(CTkFrame):
def __init__(self, master):
super().__init__(master)
self.configure(width=200)
id_label = CTkLabel(self, text = "Source file(s)", font = ("Arial",18,"bold"))
id_label.grid(row = 0, column = 0)
button_select = CTkButton(self, text="Select", command=self.select_file).grid(row = 1, column = 0)
button_check = CTkButton(self, text="Check", command=lambda: FrameMain.write_info_on_screen(self, file_path)).grid(row = 2, column = 0)
def select_file(self):
list_of_files = []
global file_path
file_path = filedialog.askopenfilenames(
title="Select a File",
initialdir=".",
filetypes=[("All files", "*.*")])
if file_path:
for i, file in enumerate(file_path):
list_of_files.append(file)
print(list_of_files)
frame_main.py(在目录 include)
import tkinter as tk
from tkinter import ttk
from customtkinter import *
class FrameMain(CTkFrame):
def __init__(self, master):
super().__init__(master)
self.configure(width=300)
def count_number_of_files(self, list_of_files):
for i,file_name in enumerate(list_of_files):
label = tk.Label(self, text=file_name).grid(row=1,column=i, padx=10, pady=10)
def write_info_on_screen(self, file_path):
FrameMain.count_number_of_files(self, file_path)
按下 button_check 之后,结果会出现在 FrameSelect,那里是小部件所在的位置。我希望结果出现在 FrameMain。
我知道会这样,因为在调用该方法时,我把 self 作为第一个参数。
尝试 self、super()、master、parent、FrameMain(CTkFrame)
FrameMain 的实例在 main.py 中,但是我该如何访问它?
解决方案
你使用 FrameMain.write_info_on_screen 和 FrameMain.count_number_of_files,但这无法访问 frame_main 的实例。
它可能需要把 frame_main 作为参数传递给 FrameSelect。
并且可能需要以不同的顺序创建帧
frame_main = FrameMain(window)
frame_select = FrameSelect(window, frame_main)
frame_select.grid(row=0, column=0, sticky="nw")
frame_main.grid(row=0, column=1, sticky="nw")
之后你可能需要把它和 self 一起放在 __init__ 中
class FrameSelect(CTkFrame):
def __init__(self, master, frame_main):
self.main_frame = frame_main
# code
并在按钮上使用它
command=lambda:self.main_frame.write_info_on_screen(self, file_path)
或者你也可以把 frame_main 分配给 window
window.frame_main = FrameMain(window)
之后所有帧都可以通过 self.master.frame_main 访问它
command=lambda:self.master.frame_main.write_info_on_screen(self, file_path)
其他帧也可以把它分配给 window,以便在其他类中访问。
使用第二种方法的完整可运行代码(单文件)。
import customtkinter as ctk # PEP8: `import *` is not preferred
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog
class FrameSelect(ctk.CTkFrame):
def __init__(self, master):
super().__init__(master)
self.configure(width=199)
self.list_of_files = [] # empty list as default value at start
id_label = ctk.CTkLabel(self, text="Source file(s)", font=("Arial", 17, "bold"))
id_label.grid(row=1, column=0)
# if you don't need to access `button_select` later then you can skip variable because it has `None` because `.grid()` gives `None
# button_select = ctk.CTkButton(self, text="Select", command=self.select_file)
# button_select.grid(row=0, column=0)
ctk.CTkButton(self, text="Select", command=self.select_file).grid(row=0, column=0)
# button_check = ctk.CTkButton(self, text="Check", command=self.check)
# button_check.grid(row=1, column=0)
ctk.CTkButton(self, text="Check", command=self.check).grid(row=1, column=0)
def select_file(self):
file_path = filedialog.askopenfilenames(
title="Select a File", initialdir=".", filetypes=[("All files", "*.*")]
)
if file_path:
# if you need to replace previous files
# self.list_of_files = file_path
# if you want to add new files and still keep previous files
self.list_of_files.extend(file_path)
print(self.list_of_files)
def check(self):
self.master.frame_main.write_info_on_screen(self.list_of_files)
class FrameMain(ctk.CTkFrame):
def __init__(self, master):
super().__init__(master)
self.configure(width=299)
self.labels = [] # to keep labels
def count_number_of_files(self, list_of_files):
# remove old labels before adding new ones
for label in self.labels:
label.destroy()
self.labels.clear()
# display new labels
for i, file_name in enumerate(list_of_files):
label = tk.Label(self, text=file_name)
label.grid(row=i, column=0, padx=10, pady=10)
self.labels.append(label)
def write_info_on_screen(self, list_of_files):
self.count_number_of_files(list_of_files)
# --- main ---
window = ctk.CTk()
window.geometry("600x800+100+100")
window.resizable(1, 1)
frame_select = FrameSelect(window)
frame_select.grid(row=0, column=0, sticky="nw")
window.frame_main = FrameMain(window)
window.frame_main.grid(row=0, column=1, sticky="nw")
window.mainloop()
第一种方法的完整可运行代码(单文件)。
import customtkinter as ctk # PEP8: `import *` is not preferred
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog
class FrameSelect(ctk.CTkFrame):
def __init__(self, master, frame_main):
super().__init__(master)
self.configure(width=199)
self.main_frame = frame_main
self.list_of_files = [] # empty list as default value at start
id_label = ctk.CTkLabel(self, text="Source file(s)", font=("Arial", 17, "bold"))
id_label.grid(row=1, column=0)
# if you don't need to access `button_select` later then you can skip variable because it has `None` because `.grid()` gives `None
# button_select = ctk.CTkButton(self, text="Select", command=self.select_file)
# button_select.grid(row=0, column=0)
ctk.CTkButton(self, text="Select", command=self.select_file).grid(
row=0, column=0
)
# button_check = ctk.CTkButton(self, text="Check", command=self.check)
# button_check.grid(row=1, column=0)
ctk.CTkButton(self, text="Check", command=self.check).grid(row=1, column=0)
def select_file(self):
file_path = filedialog.askopenfilenames(
title="Select a File", initialdir=".", filetypes=[("All files", "*.*")]
)
if file_path:
# if you need to replace previous files
# self.list_of_files = file_path
# if you want to add new files and still keep previous files
self.list_of_files.extend(file_path)
print(self.list_of_files)
def check(self):
self.main_frame.write_info_on_screen(self.list_of_files)
class FrameMain(ctk.CTkFrame):
def __init__(self, master):
super().__init__(master)
self.configure(width=299)
self.labels = [] # to keep labels
def count_number_of_files(self, list_of_files):
# remove old labels before adding new ones
for label in self.labels:
label.destroy()
self.labels.clear()
# display new labels
for i, file_name in enumerate(list_of_files):
label = tk.Label(self, text=file_name)
label.grid(row=i, column=0, padx=10, pady=10)
self.labels.append(label)
def write_info_on_screen(self, list_of_files):
self.count_number_of_files(list_of_files)
# --- main ---
window = ctk.CTk()
window.geometry("600x800+100+100")
window.resizable(1, 1)
frame_main = FrameMain(window)
frame_main.grid(row=0, column=1, sticky="nw")
frame_select = FrameSelect(window, frame_main)
frame_select.grid(row=0, column=0, sticky="nw")
window.mainloop()
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。