Кнопка Tkinter для отмены функции - PullRequest
0 голосов
/ 26 апреля 2020

Хорошо, я искал net решение, но не смог найти. В основном, когда я нажимаю одну кнопку в Tkinter GUI, запускается одна длинная функция (я говорю длинная, потому что она предназначена для копирования некоторых файлов, поэтому она потенциально может быть длинной). Поскольку я нашел много решений по схожим вопросам, используя after и after_cancel, я хотел дать ему шанс. Но вскоре я понял, что этот подход будет работать, только если моя длинная функция состоит из циклов. Поскольку моя функция состоит не из циклов, а из копирования больших файлов (без циклов, только одна команда, которая копирует указанные файлы), она не применима для моей программы. Мне нужен другой способ остановить эту функцию нажатием кнопки. Подводя итог, мне нужно нажать кнопку («кнопка отмены»), которая остановит другую функцию, которая работает в данный момент. Эта функция была запущена с другой кнопки в том же GUI. Эта функция не состоит из циклов, поэтому я не могу использовать after_cancel. Или, может быть, я могу, я думаю, что решение было бы каким-то образом преобразовать эту длинную функцию в циклы или найти другой способ остановить функцию. Последнее, что я хочу добавить, это то, что моя программа должна быть чистой GUI, консоль скрыта. Я надеюсь, что кто-то может мне помочь и сталкивался с такой проблемой раньше. С уважением

РЕДАКТИРОВАТЬ: я размещаю свой код здесь, причина, почему я не хотел делать это в первый раз, в том, что он длинный. Также я впервые использую форум. Я удалил какую-то нерелевантную часть, такую ​​как импорт модулей. Также я удалил содержимое некоторых функций, которые не включены в мой вопрос, и изменил их с описанием того, что они делают. Кроме того, в то время, когда я начал делать эту программу, я не знал, что мне следует назвать мое главное окно tkinter с root, поэтому оно называется GUI здесь.

def about_click():
    #opens file with information about my program
def viewhelp_click():
    #opens file with help for my program
def exit_click():
    #exits my program (for GUI interface)

def sync_click():
    source_dir = source_txt.get()
    target_dir = target_txt.get()

    if not os.path.exists(source_dir) and not os.path.exists(target_dir):
        source_txt.delete(0, END)
        target_txt.delete(0, END)
        messagebox.showerror("Existence", "The Source and Destination folders don't exist!")
        return
    else:
        if os.path.exists(source_dir):
            pass
        else:
            source_txt.delete(0, END)
            messagebox.showerror("Existence", "The Source folder doesn't exist!")
            return
        if os.path.exists(target_dir):
            pass
        else:
            target_txt.delete(0, END)
            messagebox.showerror("Existence", "The Destination folder doesn't exist!")
            return

    quest = messagebox.askyesno("Files", "Running this program will delete any aditional files that are in Destination folder and not in Source folder.\nAre you sure you want to proceed?")
    if quest:
        pass
    else:
        return

    loop = True
    num = 0
    loop_info = None
    while loop and num <= 3:
        num = num + 1
        sync(source_dir, target_dir, 'sync', purge=True)

        def are_dir_trees_equal(dir1, dir2):
            """
            Compare two directories recursively. Files in each directory are
            assumed to be equal if their names and contents are equal.

            @param dir1: First directory path
            @param dir2: Second directory path

            @return: True if the directory trees are the same and
                there were no errors while accessing the directories or files,
                False otherwise.
            """

            dirs_cmp = filecmp.dircmp(dir1, dir2)
            if len(dirs_cmp.left_only) > 0 or len(dirs_cmp.right_only) > 0 or \
                    len(dirs_cmp.funny_files) > 0:
                return False
            (_, mismatch, errors) = filecmp.cmpfiles(
                dir1, dir2, dirs_cmp.common_files, shallow=False)
            if len(mismatch) > 0 or len(errors) > 0:
                return False
            for common_dir in dirs_cmp.common_dirs:
                new_dir1 = os.path.join(dir1, common_dir)
                new_dir2 = os.path.join(dir2, common_dir)
                if not are_dir_trees_equal(new_dir1, new_dir2):
                    return False
            return True

        var = are_dir_trees_equal(source_dir, target_dir)
        if var:
            loop = False
            loop_info = True
        else:
            loop_info = False

    if loop_info:
        messagebox.showinfo("Completed", "Folders were synchronised successfully!")
    else:
        messagebox.showerror("Failed", "Synchronising folders failed, check folder and file attributes and try again!")

def browse1_click():
    #opens GUI dialog for choosing folder 1
def browse2_click():
    #opens GUI dialog for choosing folder 2

def resource_path(relative_path):
    #finds location of icon bundled with my program


#here was code for basic information about my main GUI window, like size, title...

#here was menu bar code for my window

#here I only left code that is relevant for my question
#this is code for button that actually starts my main function I wanna stop in my question
sync_btn = Button(GUI, text="Synchronise", font=("Segoe UI Bold", 9), command=sync_click)
sync_btn.place(height=25, width=100, x=325, y=240)



GUI.mainloop()


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