У виджета фрейма Tkinter неверный мастер / родитель - PullRequest
0 голосов
/ 15 марта 2019

Итак, программа, которую я создаю, должна показывать 2 списка внутри окна.Я собираюсь ввести фрагменты кода для того, что я считаю важным, но я добавлю весь свой код вниз, если возникнут дополнительные вопросы.Пусто это выглядит как this

Моя программа должна иметь возможность перемещать и копировать файлы из одной папки в другую, при этом обе папки отображаются с обеих сторон.Использование ООП очень важно для меня ради практики.Я также пытаюсь разделить код на Model - View - Controller, MVC-Architecture

Итак, мой графический интерфейс построен так: tk.TK имеет 4 фрейма, TopFrame, 2x мой класс 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.Весь смысл в том, чтобы заменить кнопки в функционале - в то время как на более ранних итерациях моей программы использовались кнопки для отображения найденных файлов в папке, они работают не совсем так, как предполагалось: поэтому я хочу заменить кнопки моим новым 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)

Хотя теперь у них есть только кнопка, это просто заполнитель, когда это работает, это будет значок, зависящий от файла слева, а также ярлык справа с функцией наведения ибыть в состоянии нажать много.Пока достаточно кнопки.

Когда я не использовал свой собственный вид, моя программа работала .Он поместил кнопки в правильную рамку.Но так как я заменил tk.Button на View, он делает это .

Отладка показала, что Мастер 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)

Большое спасибо, и я надеюсь, что предоставил все, что вам нужно, чтобы помочь мне.Я извиняюсь за свой английский, но также и за отсутствие комментариев, в зависимости от того, что на самом деле хуже.Другая, может быть полезная информация: использование Python 3.7.2 64-bit на ПК с Windows.

1 Ответ

1 голос
/ 15 марта 2019

В вашем FileView вы не передадите мастера своему Frame. Затем мастер по умолчанию переходит в корневое окно. Вы передаете виджет, который должен быть мастером, в FileView (self.frame_buttons), который вы принимаете как _controller (на самом деле это не так). Все, что вам нужно сделать, это передать этот виджет в качестве мастера инициализируемому фрейму:

tk.Frame.__init__(self, _controller)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...