Tkinter如何在不使用字典的情况下制作动态选项菜单

时间:2014-09-17 18:52:18

标签: python dynamic tkinter optionmenu

我找到this question,这有助于查看方法,但我想在不使用字典的情况下使用他们的方法。

基本上,在Python中我试图使用来自Tkinter的两个optionmenu,其中第一个将包含excel文档的选项卡,然后第二个将包含我从其中一个列中读取的信息从第一个选项菜单中选择。由于我不想事先存储和读取每个选项卡,因此在选择选项卡时调用函数来读取数据似乎更有效,而不是事先创建字典。有人知道这样做的方法吗?

这是我到目前为止所做的事情(excel_transfer是一个基于openpyxl的自创库 - 如果你对我正在做的事情有进一步的问题可以随意提出,否则似乎没有必要进入这个问题的目的):

import Tkinter
from Tkinter import *
from ttk import Frame
import manipulate_excel
import openpyxl
from openpyxl import load_workbook

class GUI(Frame):
    def read_tabs(self):
        wkbk = load_workbook('file.xlsx')
        sheets=wkbk.get_sheet_names()
        return sheets
    def read_columns(self):
        sheet = self.tabs_var.get()
        #if no value is selected, keep return a blank value
        if(sheet == ''):
            return ['']
        else:
            filepath = 'file.xlsx'
            workbook = excel_transfer.workbook(filepath)
            wb = workbook.open_existing_workbook()
            ws = wb(sheet)
            #step through the rows until a blank value is read
            row = 1
            current_row = 0
            previous_row = 0
            values = []
            #read the column, and append values to the array
            while current_row != None:
                previous_row = current_row
                row = row + 1
                cell = 'A' + str(row)
                current_row = workbook.read_new_cell(cell, ws)
                if(current_row != None):
                    values.append(current_row)
            #if there are no values, still return a single array value so it doesn't barf
            if(values== []):
                values= ['']
            return values

    def build_gui(self):
        n = Notebook(self)
        tab = Tkinter.LabelFrame(self, text='Tab')
        n.add(tab, text='Tab')
        n.pack()
        self.tabsvar = StringVar()
        self.tabsvar.set('')
        self.valuesvar = StringVar()
        self.valuesvar.set('')
        self.list_of_tabs = self.read_tabs()
        self.list_of_values = self.read_columns()
        self.TAB_OPTION = OptionMenu(tab, self.tabsvar, *self.list_of_tabs)
        self.TAB_OPTION.grid(row=0, column=0)
        self.VALUES_OPTION = OptionMenu(tab, self.valuesvar, *self.list_of_values)
        self.VALUES_OPTION.grid(row=1, column=0)

if __name__ == '__main__':
    root = Tk()
    app = GUI(root)
    root.mainloop()

第一个选项可以找到选项卡,但我遇到的问题是read_column仅在最初打开GUI时发生,它仍然是一个空值。我如何使self.list_of_values响应在第一个选项菜单中选择哪个选项卡?没有字典我可以使用跟踪吗?我确信有更好的方式来编写我所做的代码 - 我对建设性的批评持开放态度,因为总有很多需要学习的东西。谢谢你的帮助!

1 个答案:

答案 0 :(得分:3)

好的,所以我在继续使用它之后找到了答案,以帮助将来遇到同样问题的人。 我把self.TAB_OPTION改为:

self.TAB_OPTION(tab, self.tabsvar, *self.list_of_tabs, command=self.read_columns)

通过添加它,我必须将变量传入self.read_columns,因为添加命令会自动传递用户在第一个选项菜单中选择的值。所以,我将self.read_columns更改为:

def read_columns(self, board):
    sheet = board
    #sheet = self.tabs_var.get()

我还拿出了上面显示的评论行,因此它收到了TAB_OPTION中第一个选项菜单中选择的值,而不是读取从GUI中选择的内容。我还补充说:

self.VALUES_OPTION['menu'].delete(0, 'end')
for item in values:
    self.VALUES_OPTION['menu'].add_command(label=item)

在read_columns函数的末尾,因此它将重新生成第二个optionmenu的值。它删除所有先前的值,然后通过遍历数组添加从excel读取的每个值。我不再需要函数末尾的返回值。 我希望这有助于其他困惑的程序员:)