2017-08-12 13 views
0

私はフォルダバックアップを作成するための簡単なプログラムを開発しています。コンソールバージョンは完璧に動作しますが、私はTkinterバージョンで作業しているときに1つの問題が発生しました。私はグリッドのような方法でボタンを表示したい、各ボタンは、指定されたフォルダのバックアップを担当し、私は "ページ"あたり20ボタンを制限したいと思います。私は単純なページネーションを作成することができます。これはページ番号をインクリメントするときにのみ機能します。クラスのTkinterの要素とページ番号

Exception in Tkinter callback 
Traceback (most recent call last): 
    File "D:\Programy\Python34\lib\tkinter\__init__.py", line 1533, in __call__ 
    return self.func(*args) 
    File "D:\Rzeczy Mariusza\Python\Backup_manager\main_gui.py", line 83, in 
    go_back_event_handler self.show_avaliable_directories() 
    File "D:\Rzeczy Mariusza\Python\Backup_manager\main_gui.py", line 72, in 
    show_avaliable_directories 
    self.active_directories[i].place(x=_x, y=_y) 
    File "D:\Programy\Python34\lib\tkinter\__init__.py", line 2019, in 
    place_configure + self._options(cnf, kw)) 
_tkinter.TclError: bad window path name ".37362480.37388656" 

コード:

from tkinter import Label, StringVar 
from tkinter import ttk 


class MainGui(): 

    def __init__(self, main_frame, avaliable_directories): 
     """ 
     Building main elements located in the main_frame. 

     Args: 
      main_frame: instance - module Tkinter class ttk.Frame. 
      avaliable_directories: dict - contains avaliable directories for back up. 
     """ 

     self.main_frame = main_frame 
     self.avaliable_directories = avaliable_directories 

     self.choose_backup_dir_name = StringVar() 
     self.style_1 = ttk.Style() 
     self.style_1.map('directory.TButton', 
      foreground=[('!disabled', '#%02x%02x%02x' %(0, 0, 0)), ('disabled', '#%02x%02x%02x' %(115, 115, 115))], 
      background=[('!disabled', '#%02x%02x%02x' %(40, 240, 240)), ('disabled', '#%02x%02x%02x' %(240, 240, 240))]) 

     self.pagination = 1 
     self.button_directories = [] 
     self.active_directories = [] 

     for element in self.avaliable_directories: 
      temp = ttk.Button(
       self.main_frame, 
       width=20, 
       style='directory.TButton', 
       text=element 
       ) 
      self.button_directories.append(temp) 

     if len(self.button_directories) > 20: 
      self.go_back = ttk.Button(self.main_frame, width=2, text='<') 
      self.go_back.place(x=325, y=540) 
      self.go_back.bind('<Button-1>', self.go_back_event_handler) 

      self.go_forward = ttk.Button(self.main_frame, width=2, text='>') 
      self.go_forward.place(x=350, y=540) 
      self.go_forward.bind('<Button-1>', self.go_forward_event_handler) 

     self.show_avaliable_directories() 

    # Interesting part starts here. 
    def show_avaliable_directories(self): 
     for i, element in enumerate(self.button_directories[20*(self.pagination-1):20*self.pagination]):# Implementation of pagination. 
      _x = 20+200*(i//10) 
      _y = 20+40*(i%10) 
      element.place(x=_x, y=_y) 
      # Placed elements are assigned to new list. 
      # When discarded (bellow) all elements from the list are destroyed. 
      self.active_directories.append(element) 

    def clear_active_directories(self): 
     for element in self.active_directories: 
      element.destroy() 
     self.active_directories = [] 

    def go_back_event_handler(self, event): 
     if self.pagination > 1: 
      self.pagination -= 1 
      self.clear_active_directories() 
      self.show_avaliable_directories() 

    def go_forward_event_handler(self, event): 
     limit = (len(self.button_directories)//20)+1 
     if self.pagination < limit: 
      self.pagination += 1 
      self.clear_active_directories() 
      self.show_avaliable_directories() 

私はページ数を増やしたときにそれが動作する理由見当もつかないが、それ私は、コンソールは私にエラーを促し、ページ数を減らすかしようとすると私はページ番号を減らそうとしません。ご協力いただきありがとうございます。

答えて

0

私は粗い答えを見つけました。プログラムが新しいボタンを表示するたびに、すべての要素(ボタン)のリストが作成されます。ページが変更されると、プログラムは未使用のものであってもリスト内のすべての要素を破棄します。これは効果的ではないかもしれませんが動作します。

from tkinter import Label, StringVar 
from tkinter import ttk 


class MainGui(): 

    def __init__(self, main_frame, avaliable_directories): 
     """ 
     Building main elements located in the main_frame. 

     Args: 
      main_frame: instance - module Tkinter class ttk.Frame. 
      avaliable_directories: dict - contains avaliable directories for back up. 
     """ 

     self.main_frame = main_frame 
     self.avaliable_directories = avaliable_directories 

     self.choose_backup_dir_name = StringVar() 
     self.style_1 = ttk.Style() 
     self.style_1.map('directory.TButton', 
      foreground=[('!disabled', '#%02x%02x%02x' %(0, 0, 0)), ('disabled', '#%02x%02x%02x' %(115, 115, 115))], 
      background=[('!disabled', '#%02x%02x%02x' %(40, 240, 240)), ('disabled', '#%02x%02x%02x' %(240, 240, 240))]) 

     self.pagination = 1 
     self.button_directories = [] 

     if len(self.avaliable_directories) > 20: 
      self.go_back = ttk.Button(self.main_frame, width=2, text='<') 
      self.go_back.place(x=325, y=540) 
      self.go_back.bind('<Button-1>', self.go_back_event_handler) 

      self.go_forward = ttk.Button(self.main_frame, width=2, text='>') 
      self.go_forward.place(x=350, y=540) 
      self.go_forward.bind('<Button-1>', self.go_forward_event_handler) 

     self.show_avaliable_directories() 

    def show_avaliable_directories(self): 
     for element in self.avaliable_directories: 
      temp = ttk.Button(
       self.main_frame, 
       width=20, 
       style='directory.TButton', 
       text=element 
       ) 
      self.button_directories.append(temp) 

     for i, element in enumerate(self.button_directories[20*(self.pagination-1):20*self.pagination]): 
      _x = 20+200*(i//10) 
      _y = 20+40*(i%10) 
      element.place(x=_x, y=_y) 

    def clear_active_directories(self): 
     for element in self.button_directories: 
      element.destroy() 
     self.button_directories = [] 

    def go_back_event_handler(self, event): 
     if self.pagination > 1: 
      self.pagination -= 1 
      self.clear_active_directories() 
      self.show_avaliable_directories() 

    def go_forward_event_handler(self, event): 
     limit = (len(self.button_directories)//20)+1 
     if self.pagination < limit: 
      self.pagination += 1 
      self.clear_active_directories() 
      self.show_avaliable_directories()