微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ttk.Combobox 在不同的 tk.Listbox

如何解决ttk.Combobox 在不同的 tk.Listbox

我想要做什么:我正在尝试使用 Python 中的 tkinter(我在 Windows 上使用 3.7.7 版)构建一个 GUI,主窗口有一个列表框和第二个包含组合框的窗口。 在列表框中可以打开不同的文件。单击每个条目时,主窗口中会显示一些附加信息(这部分不在我下面的较短示例代码中)。所以我所做的是将 ListBox 绑定到一个函数,该函数通过 <<ListBoxSelect>> 事件加载和显示信息(下面代码中的 function_1)。 第二个窗口可以用一个按钮打开,应该编辑选定的文件。在第二个窗口的组合框中有不同的选项,它们根据选择的内容更改第二个窗口的其他元素。这就是为什么我将 <<ComboBoxSelected>> 事件绑定到不同的函数(下面代码中的 function_2)。

我的问题是:当我在第二个窗口的 ComboBox 中选择一个值时,绑定到第一个窗口的 ListBox 的第一个函数在正确的函数后执行组合框。这仅在第一次选择组合框的值时发生,每次创建第二个窗口时都会发生。同样在查看列表框的选定值时,它返回组合框的选定值。

编辑:我刚刚注意到这个问题只有在我之前在列表框中选择了一个项目时才会发生。所以就像我在下面所说的那样,它可能与列表框仍然处于活动状态或类似的事情有关。

我的代码和示例:

import tkinter as tk
from tkinter import ttk


class MainGUI:
    def __init__(self):
        self.root = tk.Tk()

        items = ['Test 1','Test 2','Test 3']

        self.item_Box = tk.ListBox(self.root)
        self.item_Box.insert('end',*items)
        self.item_Box.bind('<<ListBoxSelect>>',self.function_1)
        self.item_Box.pack()
        tk.Button(self.root,text='Open second window',command=self.open_window).pack()

        self.root.mainloop()

    def function_1(self,event):
        print('MainGUI function:',event)
        print('Text in ListBox:',self.item_Box.selection_get())

    def open_window(self):
        SecondGUI()


class SecondGUI:
    def __init__(self):
        self.window = tk.Toplevel()
        self.window.grab_set()

        items = ['A','B','C']

        self.dropdown = ttk.ComboBox(self.window,values=items)
        self.dropdown.current(0)
        self.dropdown.pack()
        self.dropdown.bind('<<ComboBoxSelected>>',self.function_2)

    def function_2(self,event):
        print('SecondGUI function:',event)


MainGUI()

Image of the GUI before and after the option B is clicked

选择Test 1,使用按钮打开第二个窗口并选择B后的输出如下所示:

MainGUI function: <VirtualEvent event x=0 y=0>
Text in ListBox: Test 1
SecondGUI function: <VirtualEvent event x=0 y=0>
MainGUI function: <VirtualEvent event x=0 y=0>
Text in ListBox: B

我的猜测:如果我不得不猜测问题是什么,我会说组合框可能有某种发送事件的列表框,但因为我无法找到更多关于何时以及如何发送这些事件,我真的找不到任何关于它的信息(编辑:不太可能)。查看图片时,您可以看到第一个窗口中的条目仍处于选中状态,直到单击第二个窗口中的条目为止,因此我的第二个猜测是 ListBox 仍然处于活动状态,并在它被选中时采用新的选定值点击或类似的东西(编辑:更有可能)。

我的问题:当我在不同的窗口中使用不同的小部件时,为什么第一个函数会执行,我该如何解决这个问题,或者有没有更好的方法来做到这一点?

TL;DR:当在不同窗口中选择组合框时,列表框会收到一个事件。为什么?

提前致谢!

解决方法

可能是因为 exportselection=FalseListbox 都没有设置 Combobox。 So when an item in the Combobox is selected,it will clear the selection of Listbox which triggers the <<ListboxSelect>> event.

您还使用了错误的函数self.item_box.selection_get() 来获取Listbox 的当前选定项。应改用 self.item_box.get(self.item_box.curselection())

以下更改应该可以解决问题:

class MainGUI:
    def __init__(self):
        ...
        self.item_box = tk.Listbox(self.root,exportselection=False)
        ...

    def function_1(self,event):
        print('MainGUI function:',event)
        print('Text in Listbox:',self.item_box.get(self.item_box.curselection()))

    ...

class SecondGUI:
    def __init__(self):
        ...
        self.dropdown = ttk.Combobox(self.window,values=items,exportselection=False)
        ...

    ...

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。