如何避免 tkinter <<ListboxSelect>>和 .curselection() 检测列表框之外的事件/选择? [英] How to avoid tkinter <<ListboxSelect>> and .curselection() detecting events/selection outside of Listbox?

查看:28
本文介绍了如何避免 tkinter <<ListboxSelect>>和 .curselection() 检测列表框之外的事件/选择?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下 tkinter 小部件:EntryListbox.我希望 Entry 小部件在列表框中显示选定的项目 列表框配置为允许 selectmode=tk.SINGLE.选择由 tkinter 内置的虚拟事件 <<ListboxSelect>> 触发.我的测试脚本如下所示.

I am using the following tkinter widgets: Entry and Listbox. I want the Entry widget to display a selected item in the Listbox The Listbox is configured to allow selectmode=tk.SINGLE. Selection is triggered by tkinter built-in virtual event <<ListboxSelect>>. My test script is shown below.

条目 listbox 选择时被正确更新.但是,在发生 Listbox 选择后,我遇到了以下问题:

Entry is correctly updated when a Listbox selection is made. However, I am encountering the following issues after a Listbox selection has occurred:

  1. 当鼠标指针在 Entry 中,并且发生 Left-Button Double Click 导致选择 Entry 中的项目时,抛出 2 个异常.
  2. 如果鼠标指针放在除 tkinter GUI 之外的任何窗口上,例如显示测试脚本的 IDLE 或终端或 ....等,以及当我执行 Left-Button双击 然后在该窗口中选择一个单词,或者当我故意按下 鼠标左键 来选择一个段落时,会出现与 1. 中提到的相同的异常.
  1. When the mousing pointer is in Entry, and a Left-Button Double Click takes place which leads to selecting the items in Entry, 2 exceptions is thrown up.
  2. If the mouse pointer is place over any windows other than the tkinter GUI, example over IDLE where the test script is shown or over a terminal or ....etc., and when I do a Left-Button Double Click which then selects a word in that window or when I purposely depress the Left Mouse Button to select a paragraph, the same exceptions mentioned in 1. appears.

错误如下所示.

注意:当 Listbox 中没有选择时,不会出现上述问题.

Note: The above mentioned issues do not occur when there is no selection made in the Listbox.

如何避免这两个问题?我怀疑这些问题与 <<ListboxSelect>>widget.curselection() 允许在 Listbox 之外触发但不知道如何进一步调查.

How do I avoid these two issues? I suspect these issues are related to <<ListboxSelect>> and widget.curselection() is allowed to be triggered outside of Listbox the but don't know how to investigate this further.

我想要发生什么?

  1. 不应注册鼠标指针在其他窗口或不在Listbox上的活动.
  2. Entry 中双击不应影响Listbox 中的选择.
  1. The activities of the mouse pointer when in other windows or not over Listbox should not be registered.
  2. Double clicking in Entry should not affect the selection in the Listbox.

谢谢.

测试脚本:

import tkinter as tk

class App(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.entrytext = tk.StringVar()
        self.entry = tk.Entry(textvariable=self.entrytext)
        self.listbox = tk.Listbox(selectmode=tk.SINGLE)
        self.entry.pack(side="top", fill="x")
        self.listbox.pack(side="top", fill="both", expand=True)
        for i in range(100):
            self.listbox.insert("end", "item %s" % i)
        self.listbox.bind("<<ListboxSelect>>", self.ListboxSelect)


    def ListboxSelect(self, event):
        widget = event.widget
        try:
            selection=widget.curselection()
            print('
selection = ', selection)
            selection_index = int(selection[0])
            print('selection_index = ', selection_index)
            selection_value = widget.get(selection[0])
            print("selection_value = {} ".format(selection_value))
            self.entrytext.set(selection_value)
        except:
            raise


if __name__=='__main__':
    a = App()
    a.grid()

例外情况:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python3.5/idlelib/run.py", line 119, in main
    seq, request = rpc.request_queue.get(block=True, timeout=0.05)
  File "/usr/lib/python3.5/queue.py", line 172, in get
    raise Empty
queue.Empty

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.5/tkinter/__init__.py", line 1553, in __call__
    return self.func(*args)
  File "~/entry_listbox_example.py", line 22, in ListboxSelect
    selection_index = int(selection[0])
IndexError: tuple index out of range

推荐答案

如何避免 tkinter <<ListboxSelect>>.curselection() 检测列表框外的事件/选择?

How to avoid tkinter <<ListboxSelect>> and .curselection() detecting events/selection outside of Listbox?

这完全取决于您的意思.<<ListboxSelect>> 事件被明确设计为在选择更改时触发,无论它如何更改.这可能意味着用户在列表框中选择新的内容,或者从列表框中删除选择时.

That depends on exactly what you mean. The <<ListboxSelect>> event was explicitly designed to fire whenever the selection changes, no matter how it changes. That could mean when the user selects something new in the listbox, or when the selection is removed from the listbox.

你得到的错误是因为你假设有一个选择,这可能是也可能不是真的.您需要检查选择,并且仅在选择某些内容时运行您的代码.

The errors you get are because you assume that there is a selection, which may or may not be true. You need to check for a selection and only run your code if something is selected.

另一个解决方案,或整体解决方案的一部分,可能是将列表框的 exportselection 选项设置为 False.当设置为 True - 默认值 - 任何其他小部件获得选择时,选择将被取消设置.当设置为 False 时,选择不会因为另一个小部件选择了部分或全部数据而改变.

Another solution, or part of the overall solution, might be to set the exportselection option of the listbox to False. When set to True -- the default -- the selection will be unset whenever any other widget gets the selection. When set to False, the selection won't change just because another widget gets some or all of its data selected.

这篇关于如何避免 tkinter &lt;&lt;ListboxSelect&gt;&gt;和 .curselection() 检测列表框之外的事件/选择?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆