按钮按下后的结果没有出现在预期的区域中

编程语言 2026-07-09

本项目包含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 作为第一个参数。

尝试 selfsuper()masterparentFrameMain(CTkFrame)

FrameMain 的实例在 main.py 中,但是我该如何访问它?

解决方案

你使用 FrameMain.write_info_on_screenFrameMain.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()

PEP 8 —— Python代码风格指南

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章