2011-11-29 75 views
2

加载来自pickle文件的GUI界面时遇到了一些麻烦。从pickle文件加载和修改tkinter gui

我能够做我想做的事,但它不能像我期望的那样工作,我不确定这是否正确。

这是基本的GUI的降低例子(你真的没有读它,理解它的深度,这不是主要问题):

tableRel = {} 
master = Tk() 
tableOrders = pickle.load(open(r"\\VIERNES7-3\Documentos c\sharedTableOrders.p","rb")) 


count = 0 
lOfKeys = tableOrders.keys() 
numOfTables = len(lOfKeys) 
for rowN in range((numOfTables /10)+1): 
     for colN in range(10): 
      if count == numOfTables: 
       break 
      tableN = (colN+1)+(10*(rowN)) 


      f = Frame(master,height=600,width=200, bd=1, relief=SUNKEN) 
      f.grid(row=rowN, column=colN, pady=15, padx= 0) 
      Label(f, text="Mesa: " + str(lOfKeys[count])).pack(side = TOP) 

      scrollbar = Scrollbar(f, orient=VERTICAL) 
      listbox = Listbox(f, yscrollcommand=scrollbar.set, width=19) 

      tableRel[listbox] = lOfKeys[count] 

      scrollbar.config(command=listbox.yview) 
      scrollbar.pack(side=RIGHT, fill=Y) 
      listbox.pack(side=TOP) 
      listbox.bind("<Double-Button-1>", hideOrder) 
      listbox.bind("<Return>", hideOrder) 

      index = 0 
      listbox.delete(0, END) 
      for y in tableOrders[lOfKeys[count]]["orders"]: 
       #print tableOrders[x] 
       if (y["kitchen"] == "si" or y["category"] != "Bebidas") and y["ready"] == "no": 
        listbox.insert(END, y["name"]) 
        #ordersByIndex[index] = y["name"] 
        if y["canceled"] == "si": 
         listbox.itemconfig(index, bg="red") 
        #tablesByIndex[index] = x    
        index += 1 


      count += 1 


loadFile() 
mainloop() 

现在,这是一部分,我我很困惑,我没有正确理解mainloop()这个无限循环的概念。

它一遍又一遍地做什么?

麻烦我,它是如果我把一个打印语句放在文件的任何地方,它不会一遍又一遍地打印,所以它不会重新执行文件的代码。

我基本上要实现的是,在一段时间后,gui会重新加载,如果picke文件中有更改,那么gui会更新。

我能够通过将我的代码放入一个函数(我们称之为updateGUI)并执行master.after(5000, updateGUI)来实现。

这似乎并不是最好的解决方案,因为一切都会突然变化(列表框和滚动条中选定的选项),但我想这可以通过记住状态并强加它来解决。

但我想知道是否有某种方法可以利用主循环并在文件发生更改时使gui“更新”(它不必查找文件中的更改,它必须更新每个10秒左右,然后重画屏幕。)

我试过updateupdate_idletasks,但似乎没有人重新加载pickle,并根据pickle中的新信息重新绘制它。

回答

3

主循环是您的根部件侦听并响应输入和其他事件(如鼠标单击,按键和来自操作系统的信号)的位置。通过使用after,您的利用主循环调用您的更新过程每n秒。

你可以做的另外是跟踪接口闲置了多久(没有鼠标或键盘事件)。如果它闲置并且显示有变化,您可以立即更新。如果不是空闲的,给用户一个指示器和一种手动触发更新的方法,直到它再次变为空闲。这样,用户的工作就不会被更新中断。

下面是一个计时器的简单示例,该计时器根据鼠标移动或按键进行重置。

import Tkinter as tk 

class App(): 
    def __init__(self, tick): 
     self.tick = tick 
     self.idle_time = 0 

     self.root = tk.Tk() 
     frame = tk.Frame(self.root, width=100, height=100) 
     frame.bind_all("<Motion>", self.reset_idle) 
     frame.bind_all("<Key>", self.reset_idle) 
     frame.pack() 

     self.root.after(self.tick, self.update_timer) 
     self.root.mainloop() 

    def update_timer(self): 
     print('Idle for %sms' % self.idle_time) 
     self.idle_time += self.tick 
     self.root.after(self.tick, self.update_timer) 

    def reset_idle(self, event): 
     self.idle_time = 0 

app = App(1000) 
+0

谢谢你回答抱歉的延迟,我试了一下。我唯一的问题是,如果你能指示我(如果你知道)任何代码的例子,它跟踪用户事件,如鼠标移动或点击。我正在寻找他们,但也许你已经知道一个很好的例子。 – Trufa

+0

查看我的编辑上面的例子。 –

+0

非常感谢,那正是我需要的! – Trufa