【问题标题】:Call a function on button press using value from listbox Tkinter使用列表框 Tkinter 中的值在按钮按下时调用函数
【发布时间】:2017-09-09 14:49:31
【问题描述】:

我想在按钮的命令中使用从列表框中选择的值,这样在按下“开始”按钮之前不会执行任何代码。

到目前为止,我只看到列表框通过绑定到 来执行选择元素的代码。这对我来说似乎很愚蠢,当然程序应该有某种两阶段选择,以确保用户选择他们想要的内容(切线,抱歉)。

到目前为止,我已经尝试使用 .curselection()[0] 和 .get 为当前选择创建一个变量,但我得到了一个索引错误(可能是因为最初没有选择)。然后,如果我设置了初始选择,我无法更改它,它将始终基于该选择执行。

当然,这应该很容易,但我错过了一些东西。

[编辑] 按照建议添加代码转储:

class DataVisualiser:
    def __init__(self, master):
        master.minsize(width=600, height=400)
        frame = Frame(master)
        frame.grid()

        # Histogram Generator
        hist_options = ["Cat vs. Dog", "Cat Breed", "Dog Breed", "Cat Name", "Dog Name", "Cat Location",
                        "Dog Location", "Cat Registration", "Dog Registration"]
        hist_dd = Listbox(master, bg="#cfcfcf", fg="black", font="Helvetica", height=5, selectmode=SINGLE)
        for o in hist_options:
            hist_dd.insert(0, o)
        hist_dd.grid(row=0, column=0)
        hist_dd.selection_set(first=0)
        hist_scroll = Scrollbar(master, orient=VERTICAL)
        hist_dd["yscrollcommand"] = hist_scroll.set
        hist_scroll["command"] = hist_dd.yview
        hist_scroll.grid(row=0, column=1, rowspan=7, sticky=N+S)
        # scrollbar from: https://www.youtube.com/watch?v=xNLdB0jY1Rg
        # HERE: I want to pass the value from the listbox to another function via this button
        hist_gen = Button(master, text="Go!",
                          command=lambda group=hist_dd.get(hist_dd.curselection()[0]): generate_histogram(group))
        # still need to fully implement this
        hist_gen.grid(row=6, column=0, sticky=W+E)    

def generate_histogram(group):
    print(group)
    return None

root = Tk()
dv = DataVisualiser(root)
root.mainloop()

【问题讨论】:

  • 显示您的代码将对我们所有人都有帮助。请阅读minimal reproducible example
  • GO按钮的回调函数中可以直接获取listbox项吗?
  • 用什么?正如我所说的command=lambda group=w.get(w.curselection()[0]): go(group)) 导致索引错误。

标签: python tkinter listbox


【解决方案1】:

既然你的DataVisualiser是一个类,最好改成类的其他函数方法。您的变量(或其中的一些)也应该成为类实例变量,以避免使用 global 关键字。

我使用 self 关键字 (self.group) 将 group 变量设置为实例变量,并创建了一个方法 select,该方法会在列表框选择更改时更新该变量。还使函数generate_histogram 成为类方法。您可能还需要根据整体程序目标将其他一些变量设为实例变量。

下面更新的代码有 cmets 来解释其他一些更改/添加。您可能需要根据您使用的Python 版本更改导入语句。

from Tkinter import *

class DataVisualiser:
    def __init__(self, master):
        master.minsize(width=600, height=400)
        frame = Frame(master)
        frame.grid()

        # Histogram Generator
        hist_options = ["Cat vs. Dog", "Cat Breed", "Dog Breed", "Cat Name", "Dog Name", "Cat Location",
                        "Dog Location", "Cat Registration", "Dog Registration"]
        hist_dd = Listbox(master, bg="#cfcfcf", fg="black", font="Helvetica", height=5, selectmode=SINGLE)
        for o in hist_options:
            hist_dd.insert(0, o)
        hist_dd.grid(row=0, column=0)
        hist_dd.selection_set(first=0)
        hist_scroll = Scrollbar(master, orient=VERTICAL)
        hist_dd["yscrollcommand"] = hist_scroll.set
        hist_scroll["command"] = hist_dd.yview
        hist_scroll.grid(row=0, column=1, rowspan=7, sticky=N+S)

        # scrollbar from: https://www.youtube.com/watch?v=xNLdB0jY1Rg
        # HERE: I want to pass the value from the listbox to another function via this button
        self.group = hist_dd.get(hist_dd.curselection()[0]) #make group a class variable

        # don't use default keyword parameters i.e, group= .....
        hist_gen = Button(master, text="Go!",
                          command=lambda: self.generate_histogram(self.group))
        # still need to fully implement this
        hist_gen.grid(row=6, column=0, sticky=W+E)  
        hist_dd.bind('<<ListboxSelect>>', self.select) # bind selecction event to listbox


    #method to change the 'group' variable anytime a listbox selection changes
    def select(self, event):
        widget = event.widget
        selection=widget.curselection()
        self.group = widget.get(selection[0])


    #class method
    def generate_histogram(self, group):
        print(group)
        return None

root = Tk()
dv = DataVisualiser(root)
root.mainloop()

【讨论】:

    【解决方案2】:

    为什么不在 listBox 函数中初始化一个全局变量,该函数存储在列表框中选择的值,然后按钮的回调函数可以使用该全局变量?

    下面的代码只是说明了您的代码是如何工作的。

    def getRuleAfterButtonPress(valueFromListbox):
        for index,rows in excelFile.iterrows():
            if (int(valueFromListbox)==int(rows[columns[0]][5:10])):
                rightSideText2.delete(1.0,END)
                rightSideText2.insert(END,rows[columns[7]])
    
    def onSelectFromListBox(evt):
        # Note here that Tkinter passes an event object to onselect()
        w = evt.widget
        index0 = int(w.curselection()[0])
        global valueFromListbox
        valueFromListbox = w.get(index0)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-23
      • 2013-08-21
      • 1970-01-01
      • 2011-01-18
      • 2013-02-11
      • 1970-01-01
      相关资源
      最近更新 更多