Обновление метки tkinter на основе цикла - PullRequest
0 голосов
/ 25 августа 2018

Справочная информация

Hello. В настоящее время я пытаюсь создать окно tkinter, запустить цикл for и обновить метку в режиме реального времени, поскольку цикл for проходит через каталоги (в данном случае он перечисляет все каталоги с их полными путями). в диске C моего компьютера).

Проблема

Проблема, с которой я сталкиваюсь, заключается в том, что как только я нажимаю кнопку start (которая начинает цикл for), графический интерфейс полностью зависает (я знаю, что это происходит потому, что tkinter и циклы не воспроизводятся ну, мне просто интересно, есть ли решение, о котором я не знаю), которое противоречит интуитивному принципу, так как я хотел бы, чтобы он отображал каталог, который цикл в данный момент перебирает внутри моей метки tooltip.

То, что я пробовал до сих пор

from tkinter import Tk, Label, Frame, Button
import os

def start_command():
    for root_directory, sub_directories, files in os.walk("C:\\"):
        for sub_directory in sub_directories:
            full_directory = os.path.join(root_directory, sub_directory)
            tooltip.config(text=full_directory)

window = Tk()
tooltip = Label(window, text="Nothing Here Yet")
tooltip.pack()
start = Button(text="Start", command=start_command)
start.pack()

window.mainloop()

Tl; р Я пытаюсь запустить цикл for в tkinter и обновлять метку каждую итерацию. Проблема в том, что графический интерфейс пользователя зависает с помощью приведенного выше кода.

Любая помощь будет принята с благодарностью. Спасибо за ваше время :) 1024 *

Ответы [ 2 ]

0 голосов
/ 25 августа 2018

Хотя это несколько продвинутый подход, вы можете использовать комбинацию сопрограммы , управляющей переменной tkinter и универсального виджета after() метод запустить цикл, который обновляет виджет Label с минимальными затратами времени выполнения. Хорошая особенность управляющих переменных в том, что любые виджеты, ссылающиеся на одну из них, будут автоматически обновляться каждый раз, когда ее метод set() откуда-то вызывается, поэтому вам не нужно делать это вручную.

#!/usr/bin/env python3
# /9905331/obnovlenie-metki-tkinter-na-osnove-tsikla

from tkinter import Tk, Label, Frame, Button, StringVar
import os

DELAY = 250  # Milliseconds between var updates.

def walk_dirs(start_dir):
    """ Iteratively walk directory tree from start_dir. """
    yield "Walking " + start_dir  # Optional.

    for root_directory, sub_directories, files in os.walk(start_dir):
        for sub_directory in sub_directories:
            full_directory = os.path.join(root_directory, sub_directory)
            yield full_directory

def update_variable(var, walker):
    try:
        directory = next(walker)
    except StopIteration:
        var.set("DONE!")
        return  # Don't call after() so repetitive updates stop.
    var.set(directory)  # Setting var automatically updates Label.
    tooltip.after(DELAY, update_variable, var, walker)  # Rinse and repeat.

def start_command(var):
    walker = walk_dirs("C:\\")  # Start coroutine.
    update_variable(var, walker)  # Start periodic updates using it.

window = Tk()
var = StringVar()
var.set("Nothing Here Yet")
tooltip = Label(window, textvariable=var)
tooltip.pack()
start = Button(text="Start", command=lambda: start_command(var))
start.pack()

window.mainloop()
0 голосов
/ 25 августа 2018
import tkinter as tk
import os

class MyDirectoryLabel(tk.Label):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.dirGen = self.directoryGen()
        self.master = self._nametowidget(self.winfo_parent())

    def directoryGen(self):
        for root_directory, sub_directories, files in os.walk("C:\\"):
            for sub_directory in sub_directories:
                yield os.path.join(root_directory, sub_directory)

    def loop(self):
        try:
            full_directory = next(self.dirGen)
        except StopIteration as e:
            self.config(text = "Finished...")
            return 0

        self.config(text = full_directory)

        self.master.after(10, self.loop)        

root     = tk.Tk()
root.geometry("500x100")

tooltip = MyDirectoryLabel(root, text = "Nothing Here Yet")
start   = tk.Button(root, text = "Start", command = tooltip.loop)

tooltip.pack()
start.pack()

root.mainloop()

Использует метод after в сочетании с generator, который создает каталог для метки.

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