【问题标题】:Update optionmenu dynamically tkinter动态更新选项菜单 tkinter
【发布时间】:2021-02-18 17:37:42
【问题描述】:

我正在尝试使用 tkinter 阅读 .xlsx 工作表。但是代码发布了“TypeError:'NoneType'对象不可订阅”的错误。我已经对其进行了足够的尝试,但无法理解代码的问题。

import openpyxl
from tkinter import filedialog
from tkinter import *
    
class data:

    def __init__(self,master):

        self.master = master
        master.title("App")
        master.geometry("600x200")
        master.resizable(0,0)
        
        x,y = 30,20
        self.options = ['A',"B"]
        self.om_variable = StringVar()
        # self.om_variable.set(self.options[0])
        # self.om_variable.trace('w', self.option_select)
        self.om = OptionMenu(self.master, self.om_variable, *self.options).place(x = x+300,y = y+80)
        Brw_2   = Button(master = self.master, text = 'Browse', width = 6, command=self.update_option_menu).place(x = x+500,y = y+40)

    def update_option_menu(self):

        self.om_variable.set('')
        self.om["menu"].delete(0, "end")
        xyx = self.get_SheetsName(r"C:\_Code\Inputs\SomeExcelFile.xlsx")
        print("---->",xyx)
        for string in xyx:
            self.om["menu"].add_command(label=string, 
                             command=lambda value=string: self.om_variable.set(value))           

    def get_SheetsName(self, excel_file):
        wb = openpyxl.load_workbook(excel_file)
        SH_lst = wb.sheetnames
        Sh_names = [sh for sh in SH_lst if "AllTags" in sh]
        return Sh_names

root = Tk()
myGui = data(root)
root.mainloop()

【问题讨论】:

  • 把这个:self.om = OptionMenu(self.master, self.om_variable, *self.options).place(x = x+300,y = y+80)改成这个:self.om = OptionMenu(self.master, self.om_variable, *self.options);self.om.place(x = x+300,y = y+80)
  • 是的,错误已解决,但我没有看到下拉菜单中填充任何 Excel 工作表名称。
  • 您确定您使用的openpyxl 正确吗?我对openpyxl 一无所知,所以我不能再帮你了。为什么不使用openpyxl 标签提出一个新问题?
  • 是的,这个函数在没有类的情况下工作,但不知道为什么它不能在这里工作。但不用担心,感谢您的大力帮助和“提示”。我将发布新问题。

标签: python tkinter


【解决方案1】:

这是一个常见的错误。当你写这个时:

self.om = OptionMenu(self.master, self.om_variable, *self.options).place(x = x+300,y = y+80)

Python 创建了一个选项菜单,然后调用了.place() 方法。 None 的结果保存到 self.om。您想要的是创建选项菜单,然后将其存储在self.om 然后使用.place()

所以你基本上是这样被python解释的:

temp_var = OptionMenu(self.master, self.om_variable, *self.options)
self.om = temp_var .place(x = x+300,y = y+80)
del temp_var

你应该写的是:

self.om = OptionMenu(self.master, self.om_variable, *self.options)
self.om.place(x = x+300,y = y+80)

提示:切勿在调用构造函数后直接调用grid/place/pack,而不将对象保存到变量中。

【讨论】:

    猜你喜欢
    • 2014-11-22
    • 2023-01-25
    • 1970-01-01
    • 2023-03-06
    • 2016-12-09
    • 2019-03-14
    • 1970-01-01
    • 2013-12-20
    相关资源
    最近更新 更多