2014-02-11 43 views
0

我有一個tkinter窗口,它有3個特徵:背景色,前景色和文本標籤。這些功能位於我的主文件夾中的文本配置文件(properties.conf)中。我想在配置文件更改時更新窗口功能。我使用pyinotify觀察配置文件中的更改,我想在更改時更新窗口。這是代碼:Tkinter更新其他類的值

#!/usr/bin/python 
import threading 
from Tkinter import * 
import os 
import ConfigParser 
import pyinotify 

class WatchFile(threading.Thread): 
     def run(self): 
      def onChange(ev): 
       Gui().updateGUI() 
       print 2 
      wm = pyinotify.WatchManager() 
      wm.add_watch('/home/mnrl/window_configs', pyinotify.IN_CLOSE_WRITE, onChange) 
      notifier = pyinotify.Notifier(wm) 
      notifier.loop() 

class ConfigParse(): 
     def __init__(self): 
      self.confDir = os.path.join(os.getenv('HOME'), 'window_configs/') 
      self.confFile = os.path.join(self.confDir + "properties.conf") 
      self.config = ConfigParser.ConfigParser() 

      if os.path.isfile(self.confFile): 
      self.config.read(self.confFile) 
      else: 
       if not os.path.exists(self.confDir): 
        os.makedirs(self.confDir) 
       self.config.add_section('bolum1') 
       self.config.set('section1', 'setting1', 'green') 
       self.config.set('section1', 'setting2', 'red') 
       self.config.set('section1', 'setting3', 'sample text') 

       with open(self.confFile, 'wb') as self.confFile: 
        self.config.write(self.confFile) 


class Gui(object): 
    def __init__(self): 
     self.root = Tk() 
     self.lbl = Label(self.root, text=ConfigParse().config.get('section1', 'setting3'), fg=ConfigParse().config.get('section1', 'setting1'), bg=ConfigParse().config.get('section1', 'setting2')) 
     self.lbl.pack() 

    def updateGUI(self): 
     self.lbl["text"] = ConfigParse().config.get('bolum1', 'ayar3') 
     self.lbl["fg"] = ConfigParse().config.get('bolum1', 'ayar1') 
     self.lbl["bg"] = ConfigParse().config.get('bolum1', 'ayar2') 
     self.root.update() 



WatchFile().start() 
Gui().root.mainloop() 

但每當properties.conf文件更改一個新的窗口出現更老的Tkinter窗口附近。所以tkinter窗口不更新,新的窗口打開。我該如何糾正它?

回答

2

的問題是,在WatchFile.run()你這樣做是:

 def onChange(ev): 
      Gui().updateGUI() 

這確實的東西比你期待什麼不同。它會創建一個新的GUI實例,然後立即調用其上的updateGUI()方法。因此,這兩個窗口。

你需要做的,而不是什麼,是沿着線的東西:

#!/usr/bin/env python 

gui = None 

class WatchFile(threading.Thread): 
     def run(self): 
      def onChange(ev): 
       gui.updateGUI() 

[...] 

WatchFile().start() 
gui = Gui() 
gui.root.mainloop() 

這裏創建一個變量gui,並具有分配給它的GUI類的一個實例。之後,在同一個實例上調用updateGUI()方法。

這個問題或多或少地重複你的ConfigParser類的用法,例如:

self.lbl["text"] = ConfigParse().config.get('bolum1', 'ayar3') 

在這種情況下,「作品」,因爲你的ConfigParse()類可以不兩次執行副作用效果(如打開窗口),但效率不高。您正在多次閱讀相同的文件。
什麼會更好,是隻使用一個函數(一個只有__init__定義的類實際上是相同的),運行一次,並返回一個dict

+0

你不需要'onChange'中的'global gui'語句,因爲你不會重新分配該函數的'gui'。它總是被允許讀取全局變量,你不需要特殊的聲明。 – Blckknght

+0

@Blckknght你說得對,謝謝你糾正錯誤。不知道我在想什麼。 – Carpetsmoker

+0

@Carpetsmoker非常感謝你,它工作得很好。 – mnrl