我有一个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窗口没有更新,新窗口打开。我该如何纠正?
答案 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
。