保存列表框中的选定项目以供其他类使用

Posted

技术标签:

【中文标题】保存列表框中的选定项目以供其他类使用【英文标题】:Saving selected items from a listbox for use in another class 【发布时间】:2021-05-02 22:03:21 【问题描述】:

我正在编写一段代码,其行为方式如下:

    显示项目列表框。 用户从列表框中选择一项或多项。 用户单击单独的按钮小部件以确认选择。 用户单击按钮后,顶层窗口将关闭。 选择已保存,以便程序的其他部分可以访问它。

我有以下代码(与问题无关的代码省略):

class MainWin(tk.Tk):
   # ... omitted code

    def dia(self):
        '''
        This creates a toplevel window that displays the listbox.
        '''
        TL = dialogWin(self)
        MainWin.wait_window(TL)

class dialogWin(tk.Toplevel):
    '''
    This window creates and displays the listbox.
    '''
    def __init__(self, MainWin):
       # ... omitted code
       # ...
        B = tk.Button(self, text = 'Confirm', command = self.getChoices).grid(row = 3) #This is the button that the user clicks to confirm the selection
        
        #create listbox
        self.LB = tk.Listbox(self, height = 10, width = 45, selectmode = 'multiple')
      #  ... code to configure the listbox appearence
    
    def getChoices(self):
        '''
        This is the callback function the listbox uses.
        '''
        choice = self.LB.curselection()
        self.destroy()
        return choice                  

这是我拥有的代码,但我似乎无法找到实际访问存储在choice 中的信息的方法。例如,如果我编辑 dia(self) 以确认返回值,如下所示:

def dia(self):
        TL = dialogWin(self)
        MainWin.wait_window(TL)
        print(TL.getChoices())

我收到错误 _tkinter.TclError: invalid command name ".!dialogwin.!listbox"TL.getChoices().get() 给了我同样的错误。我想要的是将所选信息保存为(1, 2, 3) 之类的东西,然后我可以从主窗口访问元组。我在这里做错了吗?

【问题讨论】:

【参考方案1】:

你很亲密。销毁窗口后,您不能再使用 tkinter 小部件方法,但您可以使用自己的方法和属性:

import tkinter as tk

class MainWin(tk.Tk):
    def __init__(self):
        super().__init__()
        tk.Button(self, text='click me', command=self.dia).pack()
        self.geometry('200x200')

    def dia(self):
        TL = dialogWin(self)
        MainWin.wait_window(TL)
        print(TL.choice)

class dialogWin(tk.Toplevel):
    def __init__(self, MainWin):
        super().__init__(MainWin)

        B = tk.Button(self, text = 'Confirm', command = self.getChoices).grid(row = 3) #This is the button that the user clicks to confirm the selection

        #create listbox
        self.LB = tk.Listbox(self, height = 10, width = 45, selectmode = 'multiple')
        self.LB.grid()
        for x in range(10):
            self.LB.insert(tk.END, f"this is item x")

    def getChoices(self):
        self.choice = self.LB.curselection() # <== save the choice as an attribute
        self.destroy()

MainWin().mainloop()

如果您愿意,也可以将其保存为主窗口的属性:

    def getChoices(self):
        self.master.choice = self.LB.curselection()
        self.destroy()

或者其他任何地方。

【讨论】:

【参考方案2】:

由于您使用了.wait_window(),这意味着您希望Toplevel() 像模态对话框一样。

下面是修改dialogWin() 以充当模态对话框:

class dialogWin(tk.Toplevel):
    '''
    This window creates and displays the listbox.
    '''
    def __init__(self, MainWin):
        super().__init__(MainWin)
        # initialize empty selected choice
        self.choice = ()

        # ... omitted code
        # ...
  
        tk.Button(self, text='Confirm', command=self.getChoices).grid(row=3) #This is the button that the user clicks to confirm the selection
        
        #create listbox
        self.LB = tk.Listbox(self, height=10, width=45, selectmode='multiple')

        #  ... code to configure the listbox appearence
    
    def getChoices(self):
        '''
        This is the callback function the listbox uses.
        '''
        # save the selected choices
        self.choice = self.LB.curselection()
        self.destroy()

    # added function to be called like a dialog
    def show(self):
        self.wait_visibility()
        self.grab_set()
        self.master.wait_window(self)
        # return the selected choices
        return self.choice

然后你可以使用dialogWin作为MainWin内部的模态对话框:

class MainWin(tk.Tk):
    def __init__(self):
        super().__init__()

        # ... omitted code

    def dia(self):
        '''
        This creates a toplevel window that displays the listbox.
        '''
        choice = dialogWin(self).show()
        print(choice)

【讨论】:

以上是关于保存列表框中的选定项目以供其他类使用的主要内容,如果未能解决你的问题,请参考以下文章

从其他窗口将新项目添加到列表框

PyQt4-如何制作一个按钮来删除组合框中的选定项目?

如何使用qstandarditemmodel获取qtableview中的数据

在泡菜文件中保存和加载多个对象?

检查列表框中的项目是不是已存在于许多其他列表框中?

如何在 sql 语句中保存组合框中的选定项目和文本框中的长数字?