Загрузите и измените графический интерфейс tkinter из файла pickle - PullRequest
2 голосов
/ 29 ноября 2011

У меня проблемы с загрузкой интерфейса GUI из файла Pickle.

Мне удалось сделать то, что я хочу, но это не работает так, как я ожидал, и я не уверен, что это правильноway.

Это сокращенный пример основного графического интерфейса (вам не нужно читать его и понимать его глубину, это не главный вопрос):

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(), которая представляет собой бесконечный цикл.

Что именно он делает снова и снова?

Что меня беспокоит, так это то, что если я помещаю оператор печати в любое место файла, он не печатается снова и снова, поэтому он не выполняет повторно код файла.

Что я в основном, чтодобиться того, чтобы через некоторое время графический интерфейс перезагружался и, если в файле picke произошли изменения, обновился графический интерфейс.

Я смог добиться этого, поместив свой код в функцию (давайте назовем ееupdateGUI) и занимаюсь master.after(5000, updateGUI).

чеЭто, кажется, не лучшее решение, потому что все меняется внезапно (выбранный параметр в списке и в свитке), но я думаю, что все это можно решить, запоминая состояние и навязывая его.

Но яИнтересно, есть ли какой-нибудь способ воспользоваться преимуществами mainloop и сделать графический интерфейс «обновленным», когда файл изменился (он не должен искать изменения в файле, он должен обновляться каждые 10 секунд или около того и перерисовыватьscreen.)

Я пробовал update и update_idletasks, но, похоже, никто не перезагружает рассол и не перерисовывает его на основании новой информации в рассоле.

1 Ответ

3 голосов
/ 30 ноября 2011

Основной цикл - это место, где ваш корневой виджет слушает и реагирует на ввод и другие события, такие как щелчки мыши, нажатия клавиш и сигналы от ОС. Используя after, вы пользуетесь преимуществами mainloop для вызова процедуры обновления каждые 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)
...