Python Tkinter无法在“选项”菜单中选择选项

2024-06-16 09:52:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个问题,我可以使用Tkinter填充两个optionmenu(第二个optionmenu动态地基于第一个),但是我注意到当我试图在第二个optionmenu中选择一个值时,它不允许我选择。我注意到在同一个GUI上,有时当运行另一个函数时,它会对另一个在运行该函数之前运行良好的选项菜单产生这种影响。选项将正确显示,并且鼠标可以扫描它们,但是当您单击其中一个选项时,它不会显示它已被选中,也不会执行对其设置的命令。以前有人遇到过这种问题吗?在

enter image description here 好吧,所以我希望其他人也有同样的问题,我会根据一些响应者的请求包含更多的代码,以防这可能会对问题有所帮助。我会尽力找出所有适用的:

class GUI(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        self.build_gui()
    #reads the tabs on an excel and inputs the tab names as the values in the first optionmenu (this works)
    def read_board_tabs(self):
        #many of these variables in the function may not be defined. Ignore them as they are taken out of context. This should just help visually see the structure.
        filepath = 'Board Control.xlsx'
        wkbk = load_workbook((filepath))
        sheets = wkbk.get_sheet_names()
        print sheets
        return sheets

    #reads content of that excel tab chosen to populate the second optionmenu (populating the option menu works, but they can't be selected once populated)
    def read_serials(self, board):
        #many of these variables in the function may not be defined. Ignore them as they are taken out of context. This should just help visually see the structure.
        sheet = board
        if(sheet == ''):
            return ['']
        else:
            filepath = 'Board Control.xlsx'
            workbook = excel_transfer.workbook(filepath)
            wb = workbook.open_existing_workbook()
            ws = workbook.activate_specific_worksheet(wb, sheet)
            row = 1
            current_row = 0
            previous_row = 0
            serials = []
            #read the serials that exist for the board selected
            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):
                    serials.append(current_row)
            if(len(serials) == 0):
                serials = ['']
            self.BOARD_SERIAL_OPTION['menu'].delete(0, 'end')
            for item in serials:
                self.BOARD_SERIAL_OPTION['menu'].add_command(label=item)  

    #this is the command that won't execute when I try to select the second optionmenu value
    def find_board_info(self, serial):
        #many of these variables in the function may not be defined. Ignore them as they are taken out of context. This should just help visually see the structure.
        self.board_checkout_status_var.set('')
        sheet = (self.boards_var).get()
        new_search = StringFound.StringSearch(serial)
        results = new_search.read_board(sheet)
        if(results == ['']):
            self.boardstatusvar.set('No board was found')
        else:
            self.boardstatusvar.set('Board: %s Serial: %s' %(results[1], serial))
            self.boardstatus_locationvar.set('Found in file: %s' %results[0])
            self.boards_var.set('%s serial %s' %(results[1], serial))
            self.dispositionvar.set(results[3])            
            self.TXvar.set(results[5])  
            self.RXvar.set(results[6])   
            self.lastvar.set(results[10])  
            self.datevar.set(results[9])
            if(results[14] != None):
                self.currentvar.set(results[10]) 
            self.locationvar.set(results[4])     
            self.imagevar.set(results[8]) 
            self.notesvar.set(results[12]) 
        self.current_board_chosen = [sheet, serial, results[15]]

    #creates the gui
    def build_gui(self):
        n = Notebook(self)
        board_process = Tkinter.LabelFrame(self, text="Board Updates")
        n.add(board_process, text='Board Signout')
        n.pack()
        self.boards_var = StringVar()
        self.boards_var.set("")
        self.serials_var = StringVar()
        self.serials_var.set("")
        self.SEARCHBOARDFRAME = Tkinter.LabelFrame(board_process, text='Find Board')
        self.SEARCHBOARDFRAME.grid(row=0, column=0, sticky='WE')
        self.BOARD_SEARCH_LABEL = Label(self.SEARCHBOARDFRAME, text='Type:')
        self.BOARD_SEARCH_LABEL.grid(row=0, column=0, sticky='W', padx=5, pady=2)
        self.BOARD_SEARCH_OPTION = OptionMenu(self.SEARCHBOARDFRAME, self.boards_var, *self.list_of_boards, command=self.read_serials) 
        self.BOARD_SEARCH_OPTION.grid(row=0, column=1, sticky='W', padx=5, pady=2)   
        self.BOARD_SERIAL_LABEL = Label(self.SEARCHBOARDFRAME, text='Serial:')
        self.BOARD_SERIAL_LABEL.grid(row=1, column=0, sticky='W', padx=5, pady=2)
        self.BOARD_SERIAL_OPTION = OptionMenu(self.SEARCHBOARDFRAME, self.serials_var, *self.list_of_serials, command=self.find_board_info)
        self.BOARD_SERIAL_OPTION.grid(row=1, column=1, sticky='W', padx=5, pady=2)

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

Tags: oftheinselfboardvarcurrentresults
1条回答
网友
1楼 · 发布于 2024-06-16 09:52:22

问题在于以下几行代码:

for item in serials:
    self.BOARD_SERIAL_OPTION['menu'].add_command(label=item)  

您正在将带有标签的项放入选项菜单中,但没有给它们命令。Optionmenu小部件存在的全部原因是向每个项目添加一个特殊的命令,该命令赋予选项菜单其行为。除非在动态创建新项时添加该命令,否则当您选择这些项时,这些项不会起任何作用—它只是一个带有标签的哑菜单。在

不幸的是,与每个项目相关联的命令是从私有工厂类(Tkinter.\u setit)返回的,因此您没有任何官方支持的方式来向选项菜单添加新项。如果您不怕使用私有命令,可以将代码更改为:

^{pr2}$

有关解决此问题的另一种方法,请参见Change OptionMenu based on what is selected in another OptionMenu

相关问题 更多 >