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

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

问题描述

我正在使用以下tkinter小部件: Entry Listbox .我希望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 选择之后,我遇到以下问题:

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 中并且发生左键双击时,会导致选择 Entry 中的项目,抛出2个异常.
  2. 如果将鼠标指针放在tkinter GUI以外的任何窗口上,例如显示测试脚本的IDLE或终端或.... etc.上方的示例,当我执行 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('\nselection = ', 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()在Listbox之外检测事件/选择?

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()在Listbox之外检测事件/选择?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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