如何进行列表框选择并根据该选择创建第二个列表框?

Posted

技术标签:

【中文标题】如何进行列表框选择并根据该选择创建第二个列表框?【英文标题】:How does one take a listbox selection and depending on that selection a second list box is created? 【发布时间】:2014-09-22 16:34:29 【问题描述】:

我有三个列表框,第一个有一定数量的选项。当用户选择一个选项时,第二个列表框需要根据之前的选择来填充。这是我尝试过的代码。我正在使用 Python 2.7 更新:

import sys
import Tkinter as TK

font = ('Times New Rome', 12, 'Bold')
Template = ''
Entrybox1 = ''
Entrybox2 = ''
Lb1 = ''
Lb2 = ''
Lb3 = ''

class smartstopkiosk_tk(TK.Tk):
    def __init__(self, parent):
        TK.Tk.__init__(self,parent)
        self.parent = parent
        self.initialize()
    
    def initialize(self):
        self.grid()
        #self.parent.title("Smartstop Kiosk")
        global Entrybox1
        global Entrybox2
        global LocalTemplate
        global Software
        seltext = ""
        software = ('Microsoft', 'Abode', 'SAP', 'Lotus  Notes', 'Jive','Cisco',     'Chrome')
        hardware = ("Computer",  "Charger", " USB Headset", "Keyboard", "Mouse", "Webcam")
        microsoft = ("Outlook", "Lync", "Word", "Excel", "PowerPoint", "Visio", "Project", "Publisher")
        adobe = ("Adobe Reader", "Java", "Flash", "Adobe Pro")
        cisco = ('IP Communicator', '')
        wireless = ("MYLOW",  "Corporate", "Visitor", "MYLTW")
        printers  = ("2N", "2S", "3N", "3S", "4N",  "4S",  "5N", "5S")      
        mobile =  ("Blackberry", "iPhone","iPad")
        AD  = ("Unlock", "Reset")
        LocalTemplate = ('User Assistance with Software.', 'User Assistance with       Hardware.', 'Mobile Device Support.',
        'Software Installation Request', 'Hardware Request', 'Wireless Connection',   'Password Reset/Username Unlocked', 
        'Add Printer')

         #creates font types
         font = ('Times New Roman', 14, 'bold')
         font2 = ('Times New Roman',12, 'bold')
    
         #Creates Instructions for Users
         stepOne = TK.LabelFrame(self, text=" 1. User Information: ", font = font2)
         stepOne.grid(row=0, columnspan=7, sticky='w', padx=5, pady=5, ipadx=5,   ipady=5)
         stepTwo = TK.LabelFrame(self, text="2. Select Program or Hardware Problems", font = font2)
         stepTwo.grid(row=3, columnspan=7, sticky='w', padx=5, pady=5, ipadx=5, ipady=5)
         stepThree = TK.LabelFrame(self, text="Please Enter the Problem or Your Request:", font = font2)
         stepThree.grid(row=6, columnspan=7, sticky='w', padx=5, pady=5, ipadx=5, ipady=5)
    
         #Creates Label for Users
         Label1 = TK.Label(stepOne, text = "First Name", font = font)
         Label1.grid(column = 2, row = 0, sticky = 'w', padx = (10, 10))
         Label2 = TK.Label(stepOne, text = "Last Name", font = font)
         Label2.grid(column = 4, row = 0, sticky = 'w', padx = (10, 10))
         Label3 = TK.Label(stepOne, text = "UserName", font = font)
         Label3.grid(column = 6, row = 0, sticky = 'w', padx = (10, 10))
    
         #Creates Entry Box for User input
         self.entry = TK.Entry(stepOne, width = 30)
         self.entry.grid(column = 2, row = 1,padx = (10, 10))
         entry2 = TK.Entry(stepOne, width = 30)
         entry2.grid(column = 4, row = 1,padx = (10, 10))
         entry3 = TK.Entry(stepOne, width = 30)
         entry3.grid(column = 6, row = 1, columnspan = 2, padx = (10, 10))
    
         #Creates User Input Box
         Usertext = TK.Text(stepThree, height = 10, width = 110, font = font)
         Usertext.grid(column = 2, row = 15, padx = (10, 10))
    
         #Creates List Boxes
         Listbox1 = TK.Listbox(stepTwo, selectmode = 'SINGLE', height = 10, width = 35, font   = font, exportselection = 0)
         Listbox1.grid(column = 2, row = 1, padx = (10, 10))
         for i in LocalTemplate:
             Listbox1.insert(TK.END, i)
         Listbox1.bind("<<ListboxSelect>>", self.selection)
         Listbox2 = TK.Listbox(stepTwo, selectmode = 'SINGLE', height = 10, width = 35, font = font, exportselection = 0)
         Listbox2.grid(column = 4, row = 1, padx = (10, 10))
         for x in seltext:
             Listbox2.insert(TK.END, x)
         Listbox2.bind("<<ListboxSelect>>", self.selection)
         Listbox3 = TK.Listbox(stepTwo, selectmode = 'SINGLE', height = 10, width = 35, font = font, exportselection = 0)
         Listbox3.grid(column = 6, row = 1, padx = (10, 10))
    
         #Creates Buttons
         Submit = TK.Button(self, text = 'Submit', font = font2)
         Submit.grid(column = 3, row = 10, sticky = 'we', padx = (10, 10))
         Startover = TK.Button(self, text = 'Cancel', font = font2)
         Startover.grid(column = 4, row = 10, sticky = 'we', padx = (10, 10))
    
         def selection(self, val):
         sender = val.Listbox1
         index = listbox1.curselection()
         value = Listbox1.get(index[0])
         if index == 1 or index == 4:
             seltext = software
         elif index == 2 or index == 5:
             seltext = hardware
         elif index == 3:
             seltext = mobile
         elif index == 6:
             seltext = wireless
         elif index == 7:
             seltext = AD
         elif index == 8:
             seltext = printer

def main():
    app = smartstopkiosk_tk(None)
    app.geometry("1300x768")

    app.mainloop()
    
if __name__ == "__main__":
    main()

我不断收到此错误 Traceback getattr 中的文件“C:\python27\lib\lib-tk\Tkinter.py”,第 1845 行 返回 getattr(self.tk, attr) 属性错误:选择

更新! 这是我如何能够在第一个列表框中包含文本并根据您的选择填充第二个列表框。

    def getchoice(event):
        seltext = ''
        INDEX = Listbox1.curselection()
        if INDEX == (0,) or INDEX == (4,):
            seltext = software
        elif INDEX == (1,) or INDEX == (5,):
            seltext = hardware
            
        elif INDEX == (2,):
            seltext = mobile
    
        elif INDEX == (3,):
            seltext = wireless
    
        elif INDEX == (6,):
            seltext = AD
        
        elif INDEX == (7,):
            seltext = printers
        print INDEX
        Listbox2.delete(0, TK.END)
        for x in seltext:
            Listbox2.insert(TK.END, x)  

        #Creates List Boxes
    Listbox1 = TK.Listbox(stepTwo, selectmode = 'SINGLE', height = 10, width = 35, font = font, exportselection = 0)
    Listbox1.grid(column = 2, row = 1, padx = (10, 10))
    for x in LocalTemplate:
        Listbox1.insert(TK.END, x)
    Listbox1.bind("<<ListboxSelect>>", getchoice)
    Listbox2 = TK.Listbox(stepTwo, selectmode = 'SINGLE', height = 10, width = 35, font = font, exportselection = 0)
    Listbox2.grid(column = 4, row = 1, padx = (10, 10))
    Listbox2.bind("<<ListboxSelect>>", getchoice2)
    Listbox3 = TK.Listbox(stepTwo, selectmode = 'SINGLE', height = 10, width = 35, font = font, exportselection = 0)
    Listbox3.grid(column = 6, row = 1, padx = (10, 10))

【问题讨论】:

好的,谢谢,错误的原因是 self.selection 不是一个选项,但我仍在努力让代码顺利运行,因此可能会在一两天... 【参考方案1】:

好的@Jobes23,这很有趣。现在您的代码中有一些“愚蠢的错误”:一开始您定义了lbl123,但改为使用label123,使lbl1 无用,有一些不必要的变量,并添加了代码,在为列表框设置变量时,您有时使用'' 和其他"",这不会影响代码,但最好有在您的代码中使用相同的约定,看起来(就像 Bryan Oakley 所说)您只是组合了来自各处的代码片段,而不考虑它们如何单独和协同工作 - 理解代码以解决问题至关重要在里面。我试图摆脱不必要的代码,但不确定你需要多少。

现在我之前说过 self.selection 不是一个选项,而是我摆脱了 listbox.bind(...) 并组成了一个带有命令的按钮,该命令导致一个函数采用所选选项并使用结果进行设置第二个列表框到一个字符串,我认为这是你想要实现的。

import Tkinter as TK

class smartstopkiosk_tk(TK.Tk):
    def __init__(self, parent):
        TK.Tk.__init__(self,parent)
        self.parent = parent
        self.initialize()

    def initialize(self):
        self.grid()
        #self.parent.title("Smartstop Kiosk")
        software = ('Microsoft', 'Abode', 'SAP', 'Lotus  Notes', 'Jive','Cisco', 'Chrome')
        hardware = ("Computer",  "Charger", " USB Headset", "Keyboard", "Mouse", "Webcam")
        microsoft = ("Outlook", "Lync", "Word", "Excel", "PowerPoint", "Visio", "Project", "Publisher")
        adobe = ("Adobe Reader", "Java", "Flash", "Adobe Pro")
        cisco = ('IP Communicator', '')
        wireless = ("MYLOW",  "Corporate", "Visitor", "MYLTW")
        printers  = ("2N", "2S", "3N", "3S", "4N",  "4S",  "5N", "5S")
        mobile =  ("Blackberry", "iPhone","iPad")
        AD  = ("Unlock", "Reset")
        LocalTemplate = ('User Assistance with Software', 'User Assistance with Hardware', 'Mobile Device Support', 'Software Installation Request', 'Hardware Request', 'Wireless Connection', 'Password Reset/Username Unlocked',
    'Add Printer')
        def getchoice2():
            print
            # use same method to find out which of the second list is chosen, and carry on.

        def getchoice():
            seltext = ''
            INDEX = Listbox1.curselection()
            if INDEX == ('0',) or INDEX == ('4',):
                seltext = software
            if INDEX == ('1',) or INDEX == ('5',):
                seltext = hardware
            if INDEX == ('2',):
                seltext = mobile
            if INDEX == ('3',):
                seltext = wireless
            if INDEX == ('6',):
                seltext = AD
            if INDEX == ('7',):
                seltext = printers
            selectchoice.config(command = getchoice2)
            for x in seltext:
                Listbox2.insert(TK.END, x)


        #creates font types
        font = ('Times New Roman', 14, 'bold')
        font2 = ('Times New Roman',12, 'bold')
        #Creates Instructions for Users
        stepOne = TK.LabelFrame(self, text=" 1. User Information: ", font = font2)
        stepOne.grid(row=0, columnspan=7, sticky='w', padx=5, pady=5, ipadx=5,   ipady=5)
        stepTwo = TK.LabelFrame(self, text="2. Select Program or Hardware Problems", font = font2)
        stepTwo.grid(row=3, columnspan=7, sticky='w', padx=5, pady=5, ipadx=5, ipady=5)
        stepThree = TK.LabelFrame(self, text="Please Enter the Problem or Your Request:", font = font2)
        stepThree.grid(row=6, columnspan=7, sticky='w', padx=5, pady=5, ipadx=5, ipady=5)
        #Creates Label for Users
        Label1 = TK.Label(stepOne, text = "First Name", font = font)
        Label1.grid(column = 2, row = 0, sticky = 'w', padx = (10, 10))
        Label2 = TK.Label(stepOne, text = "Last Name", font = font)
        Label2.grid(column = 4, row = 0, sticky = 'w', padx = (10, 10))
        Label3 = TK.Label(stepOne, text = "Mylan UserName", font = font)
        Label3.grid(column = 6, row = 0, sticky = 'w', padx = (10, 10))
        #Creates Entry Box for User input
        self.entry = TK.Entry(stepOne, width = 30)
        self.entry.grid(column = 2, row = 1,padx = (10, 10))
        entry2 = TK.Entry(stepOne, width = 30)
        entry2.grid(column = 4, row = 1,padx = (10, 10))
        entry3 = TK.Entry(stepOne, width = 30)
        entry3.grid(column = 6, row = 1, columnspan = 2, padx = (10, 10))
        #Creates User Input Box
        Usertext = TK.Text(stepThree, height = 10, width = 110, font = font)
        Usertext.grid(column = 2, row = 15, padx = (10, 10))
        #Creates List Boxes
        Listbox1 = TK.Listbox(stepTwo, selectmode = 'SINGLE', height = 10, width = 35, font   = font)
        Listbox1.grid(column = 2, row = 1, padx = (10, 10))
        for i in LocalTemplate:
            Listbox1.insert(TK.END, i)
        Listbox2 = TK.Listbox(stepTwo, selectmode = 'SINGLE', height = 10, width = 35, font = font)
        Listbox2.grid(column = 4, row = 1, padx = (10, 10))
        Listbox3 = TK.Listbox(stepTwo, selectmode = 'SINGLE', height = 10, width = 35, font = font)
        Listbox3.grid(column = 6, row = 1, padx = (10, 10))
        #Creates Buttons
        selectchoice = TK.Button(self, text = 'select my choice', font = font2, command = getchoice)
        selectchoice.grid(row = 5, column = 1, sticky = 'we', padx = (10, 10))
        Submit = TK.Button(self, text = 'Submit', font = font2)
        Submit.grid(column = 3, row = 10, sticky = 'we', padx = (10, 10))
        Startover = TK.Button(self, text = 'Cancel', font = font2)
        Startover.grid(column = 4, row = 10, sticky = 'we', padx = (10, 10))

def main():
    app = smartstopkiosk_tk(None)
    app.geometry("1300x768")
    app.mainloop()

if __name__ == "__main__":
    main()

【讨论】:

【参考方案2】:

这行是问题所在,虽然错误信息可能告诉你:

value = widget.get(selection[0])

您没有名为selection 的变量。也许您打算使用index[0] 而不是selection[0],因为您在前一行设置了index

当然,widget 也会有类似的问题,它也是未定义的。

【讨论】:

@Jobes23:在我现在看到的你的代码版本中,你有sender = val.Listbox1。在这种情况下,val 是一个事件对象,因为它是从 &lt;&lt;ListboxSelect&gt;&gt; 事件处理程序调用的。事件对象没有Listbox1 属性。也许您的意思是self.Listbox1val.widget。但是,您还有其他类似的错误,几乎就像您只是在粘贴随机代码以希望它能够正常工作一样。您正在使用尚未定义的变量,在没有这些方法的对象上调用方法等。 哦,在这一点上,我真的想尽一切办法让它发挥作用。这是一个坏主意,但如果它有效,我将能够去看看它为什么有效。

以上是关于如何进行列表框选择并根据该选择创建第二个列表框?的主要内容,如果未能解决你的问题,请参考以下文章

列表框多值选择

通过在下拉列表中选择数据库列调用 jsp 进行自动建议搜索框

如何根据使用 jQuery/AJAX 和 PHP/MySQL 选择的第一个下拉列表填充第二个下拉列表?

选择时如何让wpf listboxitem拉伸列表框的整个高度

ASP.NET MVC 多选列表框值未呈现

JQuery应用:实现下拉列表选择一项,然后在第二个下拉列表显示全部。谢谢了 请一定帮我做一下!200分!