Python Tkinter从其他类更新值

Python Tkinter从其他类更新值,python,tkinter,config,python-multithreading,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(

我有一个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窗口不更新,新窗口打开。如何更正它?

问题是在
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()类可以执行两次而不会产生副作用(例如打开窗口),但效率不是很高。您正在多次读取同一文件。

更好的方法是只使用一个函数(一个只定义了
的类实际上是相同的),运行一次,然后返回一个
dict

您不需要
onChange
中的
全局gui
语句,因为您没有从该函数重新分配
gui
。它总是允许读取全局变量,不需要特殊声明。@Blckknght你说得对,谢谢你纠正了这一点。“我不知道我在想什么。”这位烟民非常感谢,它很管用。