簡體   English   中英

tkinter - 我正在嘗試禁用前進/后退按鈕,但它似乎不起作用

[英]tkinter - I'm trying to disable the forward / backward button but it doesn't seem to work

我正在嘗試構建一個從文件夾加載圖像的圖像查看器。 它應該有前進/后退和退出按鈕。 它似乎可以很好地解決一個問題:

所以我只是用這個圖像路徑:

def get_files_from_folder(path, allowed_extensions):
    found_paths = []

    for (dir_path, _, file_names) in os.walk(path):
        for file_name in file_names:
            for allowed_extension in allowed_extensions:
                if file_name.lower().endswith(allowed_extension.lower()):
                    found_paths.append(os.path.join(dir_path, file_name))

                    break

    return found_paths

我有圖像查看器的 tkinter UI:

class UI:
    def __init__(self, icon_path, images_folder_path):
        self.current_index = 0
        self.root = tk.Tk()
        self.root.title('Images')
        self.root.iconbitmap(icon_path)

        self.button_quit = tk.Button(self.root, text = 'Quit', padx = 60, command = self.root.quit)
        self.button_forward = tk.Button(self.root, text = '>>', command = self.forward)
        self.button_backward = tk.Button(self.root, text = '<<', command = self.backward)

        self.button_quit.grid(row = 1, column = 1)
        self.button_forward.grid(row = 1, column = 2)
        self.button_backward.grid(row = 1, column = 0)

        self.images_paths = get_files_from_folder(images_folder_path, ['.jpg', '.png'])
        self.tk_images = []
        print(get_files_from_folder)
        for image_path in self.images_paths:
            self.tk_images.append(ImageTk.PhotoImage(Image.open(image_path)))

        self.current_image = tk.Label(image = self.tk_images[0])
        self.current_image.grid(column = 0, row = 0, columnspan = 3)

        self.root.mainloop()

出於某種原因,當我使用tk.DISABLED ,它不會禁用它

    def backward(self):

        if self.current_index == 0:
            self.button_backward = self.button_backward = tk.Button(self.root, text = '<<', command = self.backward, state = tk.DISABLED)

        self.current_image.grid_forget()

        self.current_index -= 1
        self.current_image = tk.Label(image = self.tk_images[self.current_index])
        self.current_image.grid(column = 0, row = 0, columnspan = 3)

前鋒相同:

    def forward(self):

        self.current_image.grid_forget()

        if self.current_index == len(self.tk_images)-1:
            self.button_forward = self.button_forward = tk.Button(self.root, text = '>>', command = self.forward, state = tk.DISABLED)
        else:
            self.button_forward.state = tk.ACTIVE
        self.current_index += 1
        self.current_image = tk.Label(image = self.tk_images[self.current_index])
        self.current_image.grid(column = 0, row = 0, columnspan = 3)

關於前進和后退Button的命令,您當前的代碼至少有幾處​​錯誤。 至於禁用Button ,可以通過調用它們的config()方法來完成——而不是通過創建一個新的或為現有的state屬性分配一個新值(即self.button_forward.state = tk.ACTIVE )。

同樣,每次按下一個按鈕並且其上的圖像發生變化時,不斷創建新的tk.Label小部件也不是一個好習慣。 最好更改現有Labelimage=選項。 這樣做通常還可以簡化需要完成的工作。

此外,您用於限制self.current_index邏輯存在缺陷,並且會使其超出范圍並發生IndexError 這比我預期的要復雜,但我想我找到了一個處理它的好方法,即將所有邏輯放在一個私有方法_change_current_index()並從前向和后向回調函數中調用它。

最后,用戶@acw1668 評論說,在程序啟動時將所有圖像加載到內存中可能會慢兩倍。 為了避免這種情況,我替換了您擁有的所有加載圖像的列表( self.tk_images ),並調用了另一個名為_open_image()新私有方法,該方法通過應用functools.lru_cache裝飾器來緩存其結果。 這使得該方法記住它已經為有限數量的索引返回了什么值,從而限制了它們在任何時候內存中的數量。

注意我還重新格式化了代碼以更好地符合PEP 8 - Python 代碼指南的樣式指南,使其更具可讀性。

from functools import lru_cache
import tkinter as tk
import os
from PIL import Image, ImageTk


class UI:
    IMG_CACHE_SIZE = 10

    def __init__(self, icon_path, images_folder_path):
        self.current_index = 0
        self.root = tk.Tk()
        self.root.title('Images')
#        self.root.iconbitmap(icon_path)

        self.button_quit = tk.Button(self.root, text='Quit', padx=60, command=self.root.quit)
        self.button_forward = tk.Button(self.root, text='>>', command=self.forward)
        self.button_backward = tk.Button(self.root, text='<<', command=self.backward)

        self.button_quit.grid(row=1, column=1)
        self.button_forward.grid(row=1, column=2)
        self.button_backward.grid(row=1, column=0)

        self.image_paths = get_files_from_folder(images_folder_path, ['.jpg', '.png'])
        self.current_image = tk.Label(image=self._open_image(0))
        self.current_image.grid(column=0, row=0, columnspan=3)

        self._change_current_index()  # Initializes fwd and bkd button states.
        self.root.mainloop()

    @lru_cache(maxsize=IMG_CACHE_SIZE)
    def _open_image(self, i):
        image_path = self.image_paths[i]
        return ImageTk.PhotoImage(Image.open(image_path))

    def backward(self):
        self._change_current_index(-1)

    def forward(self):
        self._change_current_index(1)

    def _change_current_index(self, delta=0):
        self.current_index += delta

        # Update state of forward and backward buttons based on new index value.
        bkd_state = (tk.DISABLED if self.current_index == 0 else tk.ACTIVE)
        self.button_backward.config(state=bkd_state)
        fwd_state = (tk.DISABLED if self.current_index == len(self.image_paths)-1 else tk.ACTIVE)
        self.button_forward.config(state=fwd_state)

        # Update image on Label.
        self.current_image.config(image=self._open_image(self.current_index))


def get_files_from_folder(path, allowed_extensions):
    found_paths = []
    for (dir_path, _, file_names) in os.walk(path):
        for file_name in file_names:
            for allowed_extension in allowed_extensions:
                if file_name.lower().endswith(allowed_extension.lower()):
                    found_paths.append(os.path.join(dir_path, file_name))
                    break
    return found_paths

if __name__ == '__main__':
    UI('.', './images_test')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM