Как воспроизвести класс в tkinter - PullRequest
0 голосов
/ 20 июня 2020

Я создал небольшую программу Synchronizer GUI, используя tkinter. Недавно я попытался добавить + -Button, который воспроизводит кнопки просмотра файлов и поля ввода, поэтому я могу синхронизировать c более чем 2 каталогов. (То есть лично у меня есть резервные копии моих документов и изображений на USB-накопителе, который я хочу постоянно обновлять, но я не хочу копировать весь свой каталог / home.)

У меня возникли две проблемы . Первая проблема связана с расположением кнопки «плюс»: я инициализировал количество строк равным нулю, поэтому каждый раз, когда я нажимаю кнопку +, новая строка кнопок / полей фактически находится на новой строке. к сожалению, это не работает для кнопки «плюс», которая определена вне функции, но не должна self.rowcount + = 1 настраивать количество строк для всего класса? Во-вторых, я не уверен, как обрабатывать self.sourcefile и self.targetfile: когда я выбираю новую папку, она заменяет предыдущий ввод, что не является идеей.

Я был бы очень признателен за любую помощь!

from tkinter import *
from tkinter import filedialog

class Application():
    def __init__(self):
        self.root = Tk()

        self.rowcount = 0
        self.sourcefile = ""
        self.targetfile = ""

        self.sourceDirectory = Entry(self.root, width=10)
        self.targetDirectory = Entry(self.root, width=10)
        self.sourceDirectory.insert(0, "Source")
        self.targetDirectory.insert(1, "Target")
        selectSource = Button(self.root, text = "browse source", command=self.select_source, height=15, width=15)
        selectTarget = Button(self.root, text = "browse target", command=self.select_target, height=15, width=15)
        plusButton = Button(self.root, text = "+", command=self.create_new)

        self.sourceDirectory.grid(row=0, column=0)
        self.targetDirectory.grid(row=0, column=5)
        selectSource.grid(row=0, column=1)
        selectTarget.grid(row=0, column=10)
        plusButton.grid(row=self.rowcount + 1, column=10)

        self.root.mainloop()

    def create_new(self):
        self.rowcount += 1
        print(self.rowcount)
        self.sourceDirectory = Entry(self.root, width=10)
        self.targetDirectory = Entry(self.root, width=10)
        self.sourceDirectory.insert(0, "Source")
        self.targetDirectory.insert(1, "Target")
        selectSource = Button(self.root, image=self.browsericon, command=self.select_source, height=15, width=15)
        selectTarget = Button(self.root, image=self.browsericon, command=self.select_target, height=15, width=15)

        self.sourceDirectory.grid(row=self.rowcount, column=0)
        self.targetDirectory.grid(row=self.rowcount, column=5)
        selectSource.grid(row=self.rowcount, column=1)
        selectTarget.grid(row=self.rowcount, column=10)

    def select_source(self):
        source = filedialog.askdirectory(title="Select Source")
        self.sourceDirectory.delete(0, END)
        self.sourceDirectory.insert(0, source)
        self.sourcefile = source

    def select_target(self):
        target = filedialog.askdirectory(title="Select Target")
        self.targetDirectory.delete(0, END)
        self.targetDirectory.insert(1, target)
        self.targetfile = target

Application()

1 Ответ

1 голос
/ 20 июня 2020

не должен настраивать количество строк для всего класса self.rowcount + = 1?

Да, и это делается в вашем коде. Однако изменение переменной не изменит расположение виджета, который использовал эту переменную в команде grid.

Мой совет - помещайте строки в один фрейм, а кнопки - в другой. Таким образом, вам не нужно постоянно настраивать расположение кнопок. Например:

self.row_frame = Frame(self.root)
self.button_frame = Frame(self.root)
self.button_frame.pack(side="bottom", fill="x")
self.row_frame.pack(side="top", fill="both", expand=True

Кроме того, если кнопка «+» создает новую строку, она не должна дублировать код. У вас должна быть одна функция для добавления строки. Поскольку у вас уже есть функция для этого, вы можете вызвать эту функцию в __init__.

Собирая все вместе, это выглядит примерно так:

class Application():
    def __init__(self):
        self.root = Tk()
        self.root.title("File Synchronizer")
        self.rowcount = 0
        self.sourcefile = ""
        self.targetfile = ""

        self.row_frame = Frame(self.root)
        self.button_frame = Frame(self.root)

        self.button_frame.pack(side="bottom", fill="x")
        self.row_frame.pack(side="top", fill="both", expand=True)

        startSync = Button(self.button_frame, text="Start", command=self.synchronize)
        plusButton = Button(self.button_frame, text = "+", command=self.create_new)

        startSync.grid(row=1, column=2)
        plusButton.grid(row=0, column=10)

        self.create_new()

        self.root.mainloop()

    def create_new(self):
        self.rowcount += 1
        self.sourceDirectory = Entry(self.row_frame, width=10)
        self.targetDirectory = Entry(self.row_frame, width=10)
        self.sourceDirectory.insert(0, "Source")
        self.targetDirectory.insert(1, "Target")
        selectSource = Button(self.row_frame, text = "browse source", command=self.select_source)
        selectTarget = Button(self.row_frame, text = "browse source", command=self.select_target)

        self.sourceDirectory.grid(row=self.rowcount, column=0)
        self.targetDirectory.grid(row=self.rowcount, column=5)
        selectSource.grid(row=self.rowcount, column=1)
        selectTarget.grid(row=self.rowcount, column=10)

Это не ставит кнопки «плюс» и «Пуск» находятся в одном и том же месте, но это просто потому, что это не имеет отношения к ответу. Вы можете использовать любые параметры, которые хотите разместить в рамке кнопки. Поскольку два фрейма независимы, вы можете настраивать строки, столбцы и веса в одном, не затрагивая другой. Или вы можете использовать pack в одном кадре и grid в другом.

Другая проблема с вашим кодом заключается в том, что self.sourceDirectory и self.targetDirectory могут содержать только одно значение, поэтому оно всегда будет относиться к последним созданным виджетам.

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

Например, начните с добавления пустого списка в ваше приложение методом __init__:

self.sources = []
self.targets = []

Затем, когда вы добавите новую строку, добавьте ее в список:

source_entry = Entry(self.row_frame, width=10)
target_entry = Entry(self.row_frame, width=10)
self.sources.append(source_entry)
self.targets.append(target_entry)

Затем вы можете перебирать эти два списка для обработки всех исходных и целевых значений.

Вам также придется изменить обратный вызов для функции обзора принимают индекс, чтобы кнопка знала, какую запись нужно обновить.

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