我使用的是python2.7,并使用Tkinter构建了一个UI。我使用线程和队列在主脚本工作时保持UI的响应。基本概要是脚本读取一个文本文件,解析出其中的一些信息,并将该信息放入字典和字典中的列表中,然后使用该信息发送TCP modbus请求(使用pyModbus)。然后将响应/结果写入文本文件。结果还可以通过UI中包含的文本小部件打印出来。文本小部件的更新由mainloop处理。你知道吗
我对线程和队列还是相当陌生的,我很难理解这个问题。你知道吗
我遇到的问题是,我需要在列表中的每一项循环后加入~10毫秒的睡眠时间,以便UI保持响应。如果我包括了睡眠时间,它会按预期工作,如果没有,它会冻结直到线程进程完成,然后一次更新UI(如果不使用线程的话)。10毫秒的睡眠时间可以稍微短一点。再多的量也行。你知道吗
下面是处理更新日志的代码:
textQueue = Queue.Queue()
def TextDisplay(message, disTime="false", myColor="black", bgColor="white"):
textQueue.put([message, disTime, myColor, bgColor])
class LogUI:
def __init__(self, master):
self.master = master
'''other ui elements, not relevent'''
self.mainLogFrame = Frame(self.master)
self.mainLogFrame.pack(side="top", fill="both", expand="yes", padx=5, pady=2)
self.logText = Text(self.mainLogFrame, height=2)
self.logText.pack(side="left", fill="both", expand="yes", padx=5, pady=2)
self.ThreadSafeTextDisplay()
def ThreadSafeTextDisplay(self):
while not textQueue.empty():
tempText = textQueue.get(0)
message = tempText[0]
disTime = tempText[1]
myColor = tempText[2]
bgColor = tempText[3]
message = str(message) + "\n"
'''bunch of formating stuff'''
logUI.logText.insert(END, message)
print message
#NOTE: tried to include a sleep time here, no effect
self.logText.after(10, self.ThreadSafeTextDisplay)
下面是当用户单击按钮时调用的非线程函数。你知道吗
def ParseInputFile():
'''non-threaded function, called when user clicks button'''
inputList = []
inputFile = mainUI.fullInFileEntry.get()
with open(inputFile, 'r') as myInput:
'''open file and put contents in list'''
for line in myInput:
inputList.append(line.strip())
outFile = mainUI.outFileEntry.get().strip() + '.txt'
i = 1
tableBol = False
inputDict = {}
inputKeys = []
tableID = None
for item in inputList:
'''parses out inputKeys, inputDict using regular expressions'''
runInputGetQueue.put([inputKeys, inputDict, outFile, inputFile])
以下是接收解析信息并处理modbus请求的线程函数(注意:我尝试注释实际的modbus请求,没有效果):
def RunInputThread():
time.sleep(.1)
while 1:
while not runInputGetQueue.empty():
tempGet = runInputGetQueue.get(0)
inputKeys = tempGet[0]
inputDict = tempGet[1]
outFile = tempGet[2]
inputFile = tempGet[3]
outFile = open(outFile, 'w')
TextDisplay('< Start of %s input file > ' % inputFile, True, 'blue')
for key in inputKeys:
'''loops through the keys in the dictionary'''
TextDisplay(key) #just used as an example.
for lineIndex in range(len(inputDict[key]['tableLines'])):
'''lots of code that loops thorugh the lines of input file, frequently calls the TextDisplay() function'''
TextDisplay(inputDict[key][lineIndex]) #just used as an example.
time.sleep(0.01) #UI will become unresponseive if not included.
outFile.close()
time.sleep(0.001)
找到了一种让用户界面更具响应性的方法。如上面的评论所述,队列正在接收一些东西,以使函数持续工作,从而导致UI锁定。我这样做,它将打印最多5条消息之前,采取了1毫秒的休息和召回的功能,使用户界面'赶上'。消息打印几乎一样快,因为他们进来。你知道吗
如果移动UI或调整其大小,UI将稍微没有响应。我没有问题与其他UI元素互动,而这是运行。你知道吗
如果您不介意while循环太慢,也可以将它改为if语句。我运行的一个进程从使用if语句的14秒降到使用下面的代码的5或6秒。这与将
pullCount
break
点改为1而不是5是一样的。你知道吗相关问题 更多 >
编程相关推荐