2014-02-06 6 views
1

У меня есть простой графический интерфейс, который использует привязки клавиш - что-то вроде этого.Python TkInter bind break

import Tkinter, tkFileDialog 

class Foo(object): 
    def __init__(self, master): 
     master.bind('3', self.do_bar) 
     master.bind('9', self.load_new_config) 

     self.load_config() 

     if not self.conf: 
      self.load_new_config() 
     else: 
      self.load_data() 

    def load_config(self): 
     try: 
      self.conf = #get stuff from known file 
     except FailedToGetStuff: 
      self.conf = None 

    def load_new_config(self): 
     path = askopenfilename(initialdir='~') 
     self.conf = #get stuff from file in path 
     self.load_data() 

    def load_data(self): 
     #get data from self.conf, process and display 

    def do_bar(self): 
     #do stuff with displayed data 

if __name__ == "__main__" 
    root = Tk() 
    Foo(root) 
    root.mainloop() 

Теперь это прекрасно работает, когда load_config() находит то, что искал. Я могу использовать привязки и даже после использования «9» и загрузки новой конфигурации, все работает.
Проблема в том, что если load_config() терпит неудачу, self.conf получает значение None и load_new_conf получает вызов от __init__, привязки больше не действуют.

Я понял, что проблема вызвана вызовом tkFileDialog.askopenfilename() изнутри __init__. Я не понимаю, почему это происходит и как обойти это.

+0

Вы проверили, что корень eindow имеет фокус, когда привязок перестают работать? Это может быть просто то, что ваше приложение теряет фокус. –

+0

Использование 'master.focus_set()' в конце '__init__' для принудительного сосредоточения на корне не решило проблему. – Deutherius

+0

Попробуйте следующее: 'foo = Foo (root)' – User

ответ

0

Этот код работает для меня:

import Tkinter, tkFileDialog 

class Foo(object): 
    def __init__(self, master): 
     master.bind('<KeyPress-3>', self.do_bar) 
     master.bind('<KeyPress-9>', self.load_new_config) 

     self.load_config() 

     if not self.conf: 
      master.after(1, self.load_new_config) 
     else: 
      self.load_data() 

    def load_config(self): 
     try: 
      self.conf = None#get stuff from known file 
     except FailedToGetStuff: 
      self.conf = None 

    def load_new_config(self, e = 0): 
     path = tkFileDialog.askopenfilename(initialdir='~') 
     self.conf = None#get stuff from file in path 
     self.load_data() 

    def load_data(self, e = 0): 
     pass 
     #get data from self.conf, process and display 

    def do_bar(self, e = 0): 
     print 1 
     #do stuff with displayed data 

if __name__ == "__main__": 
    root = Tkinter.Tk() 
    Foo(root) 
    root.mainloop() 
+0

Да, именно так я и сделал это в конце - просто дождитесь ввода пользователя. Это, однако, не мое намеренное поведение, я хочу, чтобы программа автоматически запрашивала новую конфигурацию. – Deutherius

+0

Отредактировано. теперь он работает для меня и при запуске. начало диалога при запуске mainloop - это ключ: 'master.after (1, self.load_new_config())' – User

+0

Большое спасибо, это работает. Однако я бы предложил одно изменение: 'master.after (1, self.load_new_config)' вместо 'master.after (1, self.load_new_config())'. В противном случае он не будет ждать указанное время, и функция будет вызвана немедленно. – Deutherius

Смежные вопросы