Tkinter框架小部件的主/父级错误

时间:2019-03-15 09:59:38

标签: python python-3.x tkinter

因此,我正在创建的程序应该在窗口内显示2个列表。我将输入我认为很重要的代码片段,但是如果接下来有其他问题,我将在整个代码中添加下来。清空,看起来像this

我的程序应该能够将文件从一个文件夹移动和复制到另一个文件夹,并且两个文件夹都显示在任一侧。出于实践考虑,使用OOP对我来说非常重要。我还试图将代码分成模型-视图-控制器,MVC体系结构

因此,我的GUI构建如下:tk.TK具有4个框架,一个TopFrame,2个DataView类和一个LowerOptionBar框架。每个DataView都包含一些按钮,一个包含框架的画布和其他一些东西。它还具有应填充框架的方法。该类如下所示:

class DataView(tk.Frame):
    def __init__(self, file_view_list, _controller):
        self.file_view_list = file_view_list
        tk.Frame.__init__(self)
        back_navigator = tk.Button(self, text='<-', height=1, width=6)
        back_navigator.grid(row=1, column=0, sticky="E")
        forwards_navigator = tk.Button(self, text='->', height=1, width=6)
        forwards_navigator.grid(row=1, column=1, sticky="E")

        search_label = tk.Label(self, text='Search:')
        search_label.grid(row=0, column=1)

        self.selected_path = tk.StringVar(self)
        self.selected_path.set("Selected Path")
        selected_path_label = tk.Label(self, textvariable=self.selected_path)
        selected_path_label.grid(row=1, column=2, columnspan=100)

        # will be added later on, to look for objects
        object_search_term = tk.StringVar() 
        object_search_entry = tk.Entry(self, textvariable=object_search_term)
        object_search_entry.grid(row=0, column=2, sticky="E")

        object_search_start = tk.Button(self, text=("Accept"))
        object_search_start.grid(row=0, column=3, sticky="W")

        self.data_canvas = tk.Canvas(self, bg="grey")
        self.data_canvas.grid(row=2, column=0, columnspan=20, sticky="news")

        self.scroll_bar = tk.Scrollbar(self, orient="vertical", command=self.data_canvas.yview, bg="pink")
        self.scroll_bar.grid(row=2, column=21, sticky='ns')
        self.data_canvas.configure(yscrollcommand=self.scroll_bar.set)

        self.frame_buttons = tk.Frame(self.data_canvas)
        self.data_canvas.create_window((0, 0), window=self.frame_buttons, anchor='nw')

    def update_list(self, file_path_list):
        print(file_path_list)
        row = 0
        for i in file_path_list:
            self.file_view_list.append(FileView(self.frame_buttons, i, 53, row))
            self.file_view_list[row].grid(column=1, row=row, sticky=tk.W)
            row +=1

        self.frame_buttons.update_idletasks()
        self.data_canvas.config(scrollregion=self.data_canvas.bbox("all"))

然后我有另一个类,称为FileView类。它的全部目的是替换Functionalit中的按钮-虽然程序的早期迭代使用按钮来显示文件夹中找到的文件,但它们并不能像预期的那样正常工作:所以我想用新的FileView替换按钮。

class FileView(tk.Frame):
   def __init__(self, _controller, _text, _width, _row):
       tk.Frame.__init__(self)
       self._controller = _controller
       self._text = _text
       self._width = _width
       that_view = tk.Button(self, text=_text, width=_width)
       that_view.pack()

   def grid_view(self, _row):
       self.grid(column=1, row=_row)

现在他们只有一个按钮,这只是一个占位符,当它起作用时,它将在左侧是一个与文件有关的图标,在右侧是一个具有悬停功能且可以单击许多功能的标签。现在,一个按钮就足够了。

当我不使用自己的视图时,我的程序worked。它将按钮放入正确的框架。但是由于我将tk.Button替换为View,所以它this确实可以。

Debunging表明,出于某种原因,FileViews的母版是我的tk.TK窗口。根据另一篇文章的介绍,手动设置母版不是一种选择,我尝试了很多事情,用谷歌搜索了所有内容,但是我找不到遇到相似之处的任何人。如果你们中的任何一个能发现错误,以及为什么视图具有错误的母版,将不胜感激。

非常感谢,我希望我能提供您所需的一切以帮助我。我赞成我的英语,但也缺乏评论,以实际情况为准

#main.py:##############################################################################
from Controller import Controller

running_controller = Controller()

running_controller.run_program()

 #View.py:##############################################################################

class DataManagerGui(tk.Tk):
    def __init__(self, _controller, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.title_font = font.Font(family='Helvetica', size=18, weight="bold", slant="italic")
        self._controller = _controller

        container = tk.Frame(self)
        container.grid()
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        page_name = TopFrame.__name__
        main_frame = TopFrame(_controller=_controller)
        main_frame.grid(row=0, column=0, sticky="nsew")

    def menubar(self):
        menu = tk.Menu(self)
        #help
        help_menu = tk.Menu(menu)
        menu.add_cascade(label="Help", menu=help_menu)
        return menu

class TopFrame(tk.Frame):

    def __init__(self, _controller):
        tk.Frame.__init__(self)
        self._controller = _controller

        label = tk.Label(self, text="Data-Manager", font='Helvitica')
        label.grid(columnspan=10, row=0, sticky="E")

        button = tk.Button(self, text="Idunfuckingknowpfg")
        button.grid(columnspan=10, row=1, sticky="E")

class DataView(tk.Frame):
    def __init__(self, file_view_list, _controller):
        self.file_view_list = file_view_list
        tk.Frame.__init__(self)
        back_navigator = tk.Button(self, text='<-', height=1, width=6)
        back_navigator.grid(row=1, column=0, sticky="E")
        forwards_navigator = tk.Button(self, text='->', height=1, width=6)
        forwards_navigator.grid(row=1, column=1, sticky="E")

        search_label = tk.Label(self, text='Search:')
        search_label.grid(row=0, column=1)

        self.selected_path = tk.StringVar(self)
        self.selected_path.set("Selected Path")
        selected_path_label = tk.Label(self, textvariable=self.selected_path)
        selected_path_label.grid(row=1, column=2, columnspan=100)

        # will be added later on, to look for objects
        object_search_term = tk.StringVar() 
        object_search_entry = tk.Entry(self, textvariable=object_search_term)
        object_search_entry.grid(row=0, column=2, sticky="E")

        object_search_start = tk.Button(self, text=("Accept"))
        object_search_start.grid(row=0, column=3, sticky="W")

        self.data_canvas = tk.Canvas(self, bg="blue")
        self.data_canvas.grid(row=2, column=0, columnspan=20, sticky="news")

        self.scroll_bar = tk.Scrollbar(self, orient="vertical", command=self.data_canvas.yview, bg="pink")
        self.scroll_bar.grid(row=2, column=21, sticky='ns')
        self.data_canvas.configure(yscrollcommand=self.scroll_bar.set)

        self.frame_buttons = tk.Frame(self.data_canvas)
        self.data_canvas.create_window((0, 0), window=self.frame_buttons, anchor='nw')

    def update_list(self, file_path_list):
        print(file_path_list)
        row = 0
        for i in file_path_list:

            # if os.path.isdir(path + '\\' + i):
                #     f_type = 'Folder'
                # elif os.path.isfile(path + '\\' + i):
                #     f_type = 'File'  

                # self.file_view_list.append(Model.File(path, i, f_type))

            self.file_view_list.append(FileView(self.frame_buttons, i, 53, row))
            self.file_view_list[row].grid(column=1, row=row, sticky=tk.W)
            row +=1

        self.frame_buttons.update_idletasks()
        self.data_canvas.config(scrollregion=self.data_canvas.bbox("all"))

        # if len(path) > 44:
        #     path = path[-44:]
        # view_inst['!dataview'].selected_path.set(path) 

class LowerOptionBar(tk.Frame):
    def __init__(self, _controller):
        self._controller = _controller
        tk.Frame.__init__(self)
        move_button = tk.Button(self, text='Move')
        move_button.grid(row=0, column=0)
        copy_button = tk.Button(self, text='Copy')
        copy_button.grid(row=0, column=1)
        delete_button = tk.Button(self, text='Delete')
        delete_button.grid(row=0, column=2)
        rename_button = tk.Button(self, text='Rename')
        rename_button.grid(row=0, column=3)
        rename_button = tk.Button(self, text='///testA\\\\\\', command=lambda: self._controller.fill_list(self.master.children, r'C:\Users\geidobler\Google Drive\Files\Programs\python\Work\DataManager\TestFolderA', 'left'))
        rename_button.grid(row=0, column=4)
        rename_button = tk.Button(self, text='///testB\\\\\\', command=lambda: self._controller.fill_list(self.master.children, r'C:\Users\geidobler\Google Drive\Files\Programs\python\Work\DataManager\TestFolderB', 'right'))
        rename_button.grid(row=0, column=5)
                                            # command=lambda i=i: controller.select_user(self, i)

class FileView(tk.Frame):
    def __init__(self, _controller, _text, _width, _row):
        tk.Frame.__init__(self)
        self._controller = _controller
        self._text = _text
        self._width = _width
        that_view = tk.Button(self, text=_text, width=_width)
        that_view.pack()

    def grid_view(self, _row):
        self.grid(column=1, row=_row)



    def menubar(self):
        menu = tk.Menu(self)
        #help
        help_menu = tk.Menu(menu)
        menu.add_cascade(label="Help", menu=help_menu)
        return menuw=_row)

#Controller.py###################################################################################

class Controller():

    def run_program(self):
        self.app = View.DataManagerGui(self)

        self.app.left_side_data_view = View.DataView([], self)
        self.app.left_side_data_view.grid(row=2, column=0)
        self.app.right_side_data_view = View.DataView([], self)
        self.app.right_side_data_view.grid(row=2, column=5)
        self.app.lower_option_bar = View.LowerOptionBar(self)
        self.app.lower_option_bar.grid(row=3, column=0)  

        self.app.mainloop()

    def delete_file(self, path):
        os.remove(path)

    def rename_file(self, old_path, new_path):
        os.rename(old_path, new_path)  

    def move_file(self, old_path, new_path):
        shutil.move(old_path, new_path)

    def copy_file(self, old_path, new_path):
        shutil.copyfile(old_path, new_path)

    def fill_list(self, view_inst, path, list):
        file_path_list = []
        row = 0
        f_type = None

        for i in os.listdir(path):
            file_path_list.append(i)

        if list == 'left':
            view_inst['!dataview'].update_list(file_path_list)
        elif list == 'right':
            view_inst['!dataview2'].update_list(file_path_list)

非常感谢,我希望我能提供您所需的一切以帮助我。我赞成我的英语,但也缺乏评论,以实际情况为准。其他可能有用的信息:在Windows PC上使用python 3.7.2 64位。

1 个答案:

答案 0 :(得分:1)

在您的"ENSG00000260727", "ENSG00000277521", "ENSG00000116514" 中,您不会将母版传递给FileView。然后,主服务器默认为根窗口。您确实将应该是母版的小部件传递给了Frame(实际上不是),您将其作为FileView接受。您要做的就是将此小部件作为主控件传递给您初始化的框架:

self.frame_buttons