首页 > 解决方案 > 如何使用默认列表和下拉菜单中的 1 个字典使 tkinter 组合框循环在课堂上工作?

问题描述

我很难解决这个问题。

我遍历 list --> "self.houses" 来构建组合框。

我使用字典“self.heroes”的键作为在下拉选项中选择的选项

最后,在选择选项之前,我需要“self.houses”列表作为组合框中的默认显示(替换空单元格)。第一个组合框“DC”,第二个组合框“Dark Horse”,最后一个组合框“Marvel”

我的实际应用程序会获取大量列表和字典,以便在表格中进行匹配和重新集成。我的大脑正在融化,所以请如果有人可以提供帮助。

import tkinter as tk
from tkinter import *
from tkinter import *
from tkinter.ttk import *

root= tk.Tk()
root.minsize(550,450)
root.maxsize(560,460)
root.title('mymyAPP')

class My_Guess(tk.Frame):

    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.parent = parent


        #keys are the options to be choosen - ITS WORKING FINE
        self.heroes = {'wonder woman':'wonder woman', 'iron man': 'iron man',
                   'astroboy':'astroboy'} 

        # list self,houses is used to create comboboxes loop - ITS WORKING FINE
                    
        #HERE IS THE PROBLEM:
        # How 'default' strings from 'self.houses' in empty combobox loop before choose
        # one and only string in each combo
        self.houses = [ 'DC', 'Dark Horse', 'Marvel'] 
        

        self.select_house_hero()
   
    def select_house_hero(self):
        
        self.definitions = self.houses
        for index, definition in enumerate(self.definitions):

            self.match_hero_house = StringVar()

            self.my_match = Combobox(self, values=(list(self.heroes.keys())),
                                               justify="center", 
                                               textvariable=self.match_hero_house,
                                               state="readonly")

            self.my_match.bind('<<ComboboxSelected>>',
                               lambda event, 
                               cmb=self.my_match: self.get_results_from_ComboBox(event, cmb))

            self.my_match.grid(row=( 1 + index),  column=0, stick='w')
            
            
    def get_results_from_ComboBox(self):
        pass

if __name__ == '__main__':
    app = My_Guess(root) 
    app.grid(row=0, column=0, sticky='nsew')
    root.mainloop()



 

标签: python-3.xloopstkinterdrop-down-menucombobox

解决方案


因此,这是您的代码的改进版本:

import tkinter as tk
import tkinter.ttk as ttk


class MyGuess(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.parent = parent

        self.heroes = ['Wonder Woman', 'Iron Man', 'Astroboy']

        self.houses = ['DC', 'Dark Horse', 'Marvel']
        self.variables = []

        self.select_house_hero()

    def select_house_hero(self):
        for index, definition in enumerate(self.houses):

            match_hero_house = tk.StringVar(value=definition)
            self.variables.append(match_hero_house)

            my_match = ttk.Combobox(self, values=self.heroes,
                                    justify="center",
                                    textvariable=match_hero_house,
                                    state="readonly")

            my_match.bind('<<ComboboxSelected>>',
                          lambda event,
                          cmb=my_match: self.get_results_from_combobox(event, cmb))

            my_match.grid(row=index + 1, column=0, stick='w')

    def get_results_from_combobox(self, event, cmb):
        pass


if __name__ == '__main__':
    root = tk.Tk()
    root.minsize(550, 450)
    root.maxsize(560, 460)
    root.title('My App')

    app = MyGuess(root)
    app.grid(row=0, column=0, sticky='nsew')

    root.mainloop()

首先将所有定义之外的内容移到 中,if __name__ == '__main__':否则您将Tk在导入文件时创建另一个实例。

然后还删除所有*导入,要么导入你需要的东西,要么像这里一样导入整个模块(这里它也使用别名)。

您似乎也没有理由将其self.heroes作为字典,因此我将其更改为列表。

重要的部分是您需要保存对所有StringVars 的引用,否则它们将被垃圾收集,因此我创建了一个属性,该属性variables是一个列表,将用于select_house_hero将变量附加到。在self_house_hero你不需要创建新的实例变量时,让它们都是本地的,因为它们无论如何都只有最后一个值。还将值设置StringVar为您希望显示为组合框的“标题”的值。

PEP 8 还建议类名是CapitalCase(而不是Capital_Snake_Case或任何会被调用的)


推荐阅读