简体   繁体   English

动态更新选项菜单 tkinter

[英]Update optionmenu dynamically tkinter

I am trying to read.xlsx worksheets using tkinter.我正在尝试使用 tkinter 读取.xlsx 工作表。 But code is posting error of "TypeError: 'NoneType' object is not subscribable".但代码发布错误“TypeError:'NoneType' object 不可订阅”。 I have made enough trial on it but not able to understand the issue with the code.我已经对其进行了足够的试验,但无法理解代码的问题。

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()

This is a common mistake.这是一个常见的错误。 When you wrote this:当你写这个:

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

Python created an optionmenu and then called the .place() method. Python 创建了一个选项菜单,然后调用.place()方法。 The result of that which is None is saved to self.om . None的结果被保存到self.om What you want is for the optionmenu to be created then stored in self.om then placed using .place()您想要的是创建选项菜单,然后将其存储在self.om中,然后使用.place()放置

So you basically python interpreted it like this:所以你基本上 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

What you should have written is:你应该写的是:

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

Tip: never directly call grid / place / pack after calling the constructor without saving the object to a variable.提示:在没有将 object 保存到变量的情况下,切勿在调用构造函数后直接调用grid / place / pack

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM