python - 如何从文本文件向 OptionMenu 添加选项

标签 python python-3.x tkinter optionmenu

我正在为我的类(class)编写一个程序,即使在关闭程序后,您也可以制作食谱、保存和编辑它。您显然需要一个文本文件来执行此操作。

我正在使用 OptionMenu(Tkinter,Python 3.3.3),但我无法弄清楚如何继续更新它以在我的文本文件中创建列表中的第一个选项。那我该怎么做呢?

因此我的代码是:

###########################################
###########################################
### RECIPE BOOK TASK ##### By 18166 #######
###########################################
###########################################

from tkinter import *


def script ():

    #### MAIN ####

    fake_window = Tk()
    new_recipe_window = fake_window
    start_window = fake_window
    start_window.title("Recipe Book Task")

    #### MAIN ####



    ## DATA FILE ##

    global datafile
    datafile = open("StoredRecipes.txt", "a+")

    ## DATA FILE ##



    ### Functions ###

    def close (x):                                                             ## Close Original Window ##
        global start_window
        global new_recipe_window
        (x).withdraw()

    def new_recipe ():
        new_recipe_window = Tk()                                                ## Making new window ##
        new_recipe_window.title("New Recipe")
        close(start_window)

        recipe_name_label = Label(new_recipe_window, text="Recipe Name: ")      ## Making new recipe label ##
        recipe_name_label.grid(row=0, column=0)
        recipe_name_box = Entry(new_recipe_window)                              ## Making new recipe entry ##
        recipe_name_box.grid(row=0, column=1)

        num_people_label = Label(new_recipe_window, text="Number of people: ")  ## Making number of people label ##
        num_people_label.grid(row=1, column=0)
        num_people_box = Entry(new_recipe_window)                               ## Making number of people entry ##
        num_people_box.grid(row=1, column=1)

        item_label = Label(new_recipe_window, text="Items: ")                   ## Making item label ##
        item_label.grid(row=2, column=0)
        item_box = Entry(new_recipe_window)                                     ## Making item entry ##
        item_box.grid(row=2, column=1)

        quantity_label = Label(new_recipe_window, text="Quantity: ")            ## Making quantity label ##
        quantity_label.grid(row=3, column=0)
        quantity_box = Entry(new_recipe_window)                                 ## Making quantity entry ##
        quantity_box.grid(row=3, column=1)

        unit_label = Label(new_recipe_window, text="Unit: ")                    ## Making unit label ##
        unit_label.grid(row=4, column=0)
        unit_box = Entry(new_recipe_window)                                     ## Making unit entry ##
        unit_box.grid(row=4, column=1)

        def write ():
            a = recipe_name_box.get()
            b = num_people_box.get()
            c = item_box.get()
            d = quantity_box.get()
            e = unit_box.get()

            line = (a, b, c, d, e)
            datafile.write(str(line) + "\n")
            datafile.close()

            saved_recipes.config(a)

            close(new_recipe_window)

            script()



        finish_button = Button(new_recipe_window, text="Save and Finish", command=write)       ## Making finish button ##
        finish_button.grid(row=5, column=0, sticky=S)




    # Dropdown Box #

    default = StringVar(start_window, 'Recipe 1')
    default.set("Select Your Recipe")

    saved_recipes = OptionMenu(start_window, default,  "Hi")
    saved_recipes.grid(row=0, column=1)

    # Dropdown Box #



    # New Recipe Button #

    new_recipe = Button(start_window, text="New Recipe", command=new_recipe)
    new_recipe.grid(row=0, column=0)

    # New Recipe Button #

script()

(抱歉打扰了,我想所有的回答都可能对回答有用吗?)

最佳答案

我相信您有两种不同的选择。

您可以做的一个选择是设置一个计时器,每隔几秒钟检查一次文本文件,看看它是否有任何变化,然后相应地更新您的 OptionMenu。您可以找到有关如何执行此操作的更多信息 here ,但简而言之,您希望您的代码看起来像这样:

def recheck(root, option_menu, file_name):
    with open(file_name) as my_file:
        lines = my_file.readlines():
        # `lines` is a list where each item is a single line
        # do any checks and updates you need here.

    root.after(1000, recheck, root, option_menu, file_name)  
    # schedule the function to run again after 1000 milliseconds.

def script():
    # set up your gui

    start_window.after(1000, recheck, start_window, option_menu, "StoredRecipies.txt") 

注意:您可以在此处找到有关 with 语句的更多信息:http://effbot.org/zone/python-with-statement.htm

这样做的缺点是更新会有点滞后——您最终每秒只会重新检查一次文件,因此更新不会是即时的。

或者,您可以使用类似 Watchdog 的内容.这是一个第 3 方库,您可以将其设置为“监视”特定文件并在文件更改时运行函数。它的响应速度更快,因为只有当文件实际更改时您才会调用该函数,但最终可能会变得更加复杂,因为您需要弄清楚如何使其与 Tkinter 一起工作。我猜测您的代码大致如下所示:

import os.path
from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer

def setup_observer(option_menu, filename):
    normalized_filename = os.path.normpath(input_filename)

    class MyEvent(FileSystemEventHandler):
        def on_modified(self, event):
            if os.path.normpath(event.src_path) == normalized_filename:
                # update your option menu

    observer = Observer()
    observer.schedule(MyEvent(), '.', recursive=False)
    return observer

def script():
    # setup gui

    observer = setup_observer(option_menu, "myfile.txt")

    start_window.mainloop()

关于python - 如何从文本文件向 OptionMenu 添加选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27678268/

相关文章:

python - pip 无法安装枕头

python - 从 Python 脚本中激活 virtualenv

python - 在 Pandas 中将字典转换为对称/距离矩阵的最有效方法

python - 如何更新 Tkinter 标签?

python - 使用 tkinter 获取多行(域名)

python - 为什么我从另一个类继承时 __init__() 必须使用两次?

python - 如何将类方法的输出获取到全局变量中

python - 防止注释显示在图形区域之外

python - 循环中定义的单元格变量

python-3.x - 如何用鼠标画图并保存为1和0