Tkinter更新其他类的值

时间:2014-02-11 00:19:19

标签: python tkinter config python-multithreading

我有一个tkinter窗口,它有3个功能:背景颜色,前景色和文本标签。这些功能位于我的主文件夹中的文本配置文件(properties.conf)中。我想在配置文件更改时更新窗口功能。我用pyinotify观察配置文件中的更改,我想在更改时更新窗口。这是代码:

#!/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窗口没有更新,新窗口打开。我该如何纠正?

1 个答案:

答案 0 :(得分:2)

问题在于WatchFile.run()你在做这件事:

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

这与你期望的不同。它会创建一个 new 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