Python ttk.combobox 强制发布/打开

2024-05-08

我正在尝试扩展 ttk 组合框类以允许自动建议。我到目前为止的代码运行良好,但我想让它在输入一些文本后显示下拉列表,而不从小部件的输入部分移除焦点。

我正在努力解决的部分是找到一种强制下拉的方法,在 python 文档中我找不到任何提及这一点的内容,但是在 tk 文档中我确实找到了一个我认为应该执行此操作的 post 方法,但它没有t 似乎是在 python 包装器中实现的。

我还尝试在自动建议发生后生成向下箭头键事件,但是,虽然这确实显示了下拉列表,但它会删除焦点,并且尝试在此事件后设置焦点似乎也不起作用(焦点不会返回)

有谁知道我可以用来实现此目的的功能吗?

我的代码适用于仅使用标准库的 python 3.3:

class AutoCombobox(ttk.Combobox):
    def __init__(self, parent, **options):
        ttk.Combobox.__init__(self, parent, **options)
        self.bind("<KeyRelease>", self.AutoComplete_1)
        self.bind("<<ComboboxSelected>>", self.Cancel_Autocomplete)
        self.bind("<Return>", self.Cancel_Autocomplete)
        self.autoid = None

    def Cancel_Autocomplete(self, event=None):
        self.after_cancel(self.autoid) 

    def AutoComplete_1(self, event):
        if self.autoid != None:
            self.after_cancel(self.autoid)
        if event.keysym in ["BackSpace", "Delete", "Return"]:
            return
        self.autoid = self.after(200, self.AutoComplete_2)

    def AutoComplete_2(self):
        data = self.get()
        if data != "":
            for entry in self["values"]:
                match = True
                try:
                    for index in range(0, len(data)):
                        if data[index] != entry[index]:
                            match = False
                            break
                except IndexError:
                    match = False
                if match == True:
                    self.set(entry)
                    self.selection_range(len(data), "end")
                    self.event_generate("<Down>",when="tail")
                    self.focus_set()
                    break
            self.autoid = None

下面演示了使用工具提示实现此用户体验的解决方法。这是使用实现的PySimpleGUI,但应该很容易适应“纯”tkinter。

from functools import partial
from typing import Callable, Any

from fuzzywuzzy import process, fuzz
import PySimpleGUI as sg


# SG: Helper functions:
def clear_combo_tooltip(*_, ui_handle: sg.Element, **__) -> None:
    if tt := ui_handle.TooltipObject:
        tt.hidetip()
        ui_handle.TooltipObject = None


def show_combo_tooltip(ui_handle: sg.Element, tooltip: str) -> None:
    ui_handle.set_tooltip(tooltip)
    tt = ui_handle.TooltipObject
    tt.y += 40
    tt.showtip()


def symbol_text_updated(event_data: dict[str, Any], all_values: list[str], ui_handle: sg.Element) -> None:
    new_text = event_data[ui_handle.key]
    if new_text == '':
        ui_handle.update(values=all_values)
        return
    matches = process.extractBests(new_text, all_values, scorer=fuzz.ratio, score_cutoff=40)
    sym = [m[0] for m in matches]
    ui_handle.update(new_text, values=sym)

    # tk.call('ttk::combobox::Post', ui_handle.widget)  # This opens the list of options, but takes focus
    clear_combo_tooltip(ui_handle=ui_handle)
    show_combo_tooltip(ui_handle=ui_handle, tooltip="\n".join(sym))


# Prepare data:
all_symbols = ["AAPL", "AMZN", "MSFT", "TSLA", "GOOGL", "BRK.B", "UNH", "JNJ", "XOM", "JPM", "META", "PG", "NVDA", "KO"]

# SG: Layout
sg.theme('DarkAmber')
layout = [
    [
        sg.Text('Symbol:'),
        sg.Combo(all_symbols, enable_per_char_events=True, key='-SYMBOL-')
    ]
]

# SG: Window
window = sg.Window('Symbol data:', layout, finalize=True)
window['-SYMBOL-'].bind("<Key-Down>", "KeyDown")

# SG: Event loop
callbacks: dict[str: Callable] = {
    '-SYMBOL-': partial(symbol_text_updated, all_values=all_symbols, ui_handle=window['-SYMBOL-']),
    '-SYMBOL-KeyDown': partial(clear_combo_tooltip, ui_handle=window['-SYMBOL-']),
}
unhandled_event_callback = partial(lambda x: print(f"Unhandled event key: {event}. Values: {x}"))

while True:
    event, values = window.read()
    if event in (sg.WIN_CLOSED, 'Exit'):
        break
    callbacks.get(event, unhandled_event_callback)(values)


# SG: Cleanup
window.close()

该解决方案的灵感来自这个要点 https://gist.github.com/vq75/9e6eb8e6d92e6914279734de3646c6d3 and 这次讨论 https://github.com/PySimpleGUI/PySimpleGUI/issues/820.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python ttk.combobox 强制发布/打开 的相关文章

  • 通过 Scrapy 抓取 Google Analytics

    我一直在尝试使用 Scrapy 从 Google Analytics 获取一些数据 尽管我是一个完全的 Python 新手 但我已经取得了一些进展 我现在可以通过 Scrapy 登录 Google Analytics 但我需要发出 AJAX
  • 将 Matplotlib 误差线放置在不位于条形中心的位置

    我正在 Matplotlib 中生成带有错误栏的堆积条形图 不幸的是 某些层相对较小且数据多样 因此多个层的错误条可能重叠 从而使它们难以或无法读取 Example 有没有办法设置每个误差条的位置 即沿 x 轴移动它 以便重叠的线显示在彼此
  • OpenCV Python cv2.mixChannels()

    我试图将其从 C 转换为 Python 但它给出了不同的色调结果 In C Transform it to HSV cvtColor src hsv CV BGR2HSV Use only the Hue value hue create
  • Django:按钮链接

    我是一名 Django 新手用户 尝试创建一个按钮 单击该按钮会链接到我网站中的另一个页面 我尝试了一些不同的例子 但似乎没有一个对我有用 举个例子 为什么这不起作用
  • 从字符串中删除识别的日期

    作为输入 我有几个包含不同格式日期的字符串 例如 彼得在16 45 我的生日是1990年7月8日 On 7 月 11 日星期六我会回家 I use dateutil parser parse识别字符串中的日期 在下一步中 我想从字符串中删除
  • shap.TreeExplainer 和 shap.Explainer 条形图之间的区别

    对于下面给出的代码 我得到了不同的条形图shap values 在此示例中 我的数据集为 1000train样本有 9 个类别和 500 个test样品 然后 我使用随机森林作为分类器并生成模型 当我开始生成shap条形图在这两种情况下得到
  • 是否可以忽略一行的pyright检查?

    我需要忽略一行的pyright 检查 有什么特别的评论吗 def create slog group SLogGroup data Optional dict None SLog insert one SLog group group da
  • 从 Flask 访问 Heroku 变量

    我已经使用以下命令在 Heroku 配置中设置了数据库变量 heroku config add server xxx xxx xxx xxx heroku config add user userName heroku config add
  • 如何在Python中获取葡萄牙语字符?

    我正在研究葡萄牙语 角色看起来很奇怪 我怎样才能解决这个问题 代码 import feedparser import random Vou definir os feeds feeds conf feedurl http pplware s
  • 添加不同形状的 numpy 数组

    我想添加两个不同形状的 numpy 数组 但不进行广播 而是将 缺失 值视为零 可能最简单的例子是 1 2 3 2 gt 3 2 3 or 1 2 3 2 1 gt 3 2 3 1 0 0 我事先不知道形状 我正在弄乱每个 np shape
  • 如何在ipywidget按钮中显示全文?

    我正在创建一个ipywidget带有一些文本的按钮 但按钮中未显示全文 我使用的代码如下 import ipywidgets as widgets from IPython display import display button wid
  • Pygame:有没有简单的方法可以找到按下的任何字母数字的字母/数字?

    我目前正在开发的游戏需要让人们以自己的名义在高分板上计时 我对如何处理按键有点熟悉 但我只处理过寻找特定的按键 有没有一种简单的方法可以按下任意键的字母 而不必执行以下操作 for event in pygame event get if
  • IO 密集型任务中的 Python 多线程

    建议仅在 IO 密集型任务中使用 Python 多线程 因为 Python 有一个全局解释器锁 GIL 只允许一个线程持有 Python 解释器的控制权 然而 多线程对于 IO 密集型操作有意义吗 https stackoverflow c
  • 在f字符串中转义字符[重复]

    这个问题在这里已经有答案了 我遇到了以下问题f string gt gt gt a hello how to print hello gt gt gt f a a gt gt gt f a File
  • python获取上传/下载速度

    我想在我的计算机上监控上传和下载速度 一个名为 conky 的程序已经在 conky conf 中执行了以下操作 Connection quality alignr wireless link qual perc wlan0 downspe
  • 如何在Python中对类别进行加权随机抽样

    给定一个元组列表 其中每个元组都包含一个概率和一个项目 我想根据其概率对项目进行采样 例如 给出列表 3 a 4 b 3 c 我想在 40 的时间内对 b 进行采样 在 python 中执行此操作的规范方法是什么 我查看了 random 模
  • Conda SafetyError:文件大小不正确

    使用创建 Conda 环境时conda create n env name python 3 6 我收到以下警告 Preparing transaction done Verifying transaction SafetyError Th
  • Python:如何将列表列表的元素转换为无向图?

    我有一个程序 可以检索 PubMed 出版物列表 并希望构建一个共同作者图 这意味着对于每篇文章 我想将每个作者 如果尚未存在 添加为顶点 并添加无向边 或增加每个合著者之间的权重 我设法编写了第一个程序 该程序检索每个出版物的作者列表 并
  • Rocket UniData/UniVerse:ODBC 无法分配足够的内存

    每当我尝试使用pyodbc连接到 Rocket UniData UniVerse 数据时我不断遇到错误 pyodbc Error 00000 00000 Rocket U2 U2ODBC 0302810 Unable to allocate
  • 导入错误:没有名为 site 的模块 - mac

    我已经有这个问题几个月了 每次我想获取一个新的 python 包并使用它时 我都会在终端中收到此错误 ImportError No module named site 我不知道为什么会出现这个错误 实际上 我无法使用任何新软件包 因为每次我

随机推荐

  • textFieldDidChangeSelection:在视图更新期间修改状态,这将导致未定义的行为

    这是我的代码 struct CustomTextField UIViewRepresentable var placeholder String Binding var text String func makeUIView context
  • 敲除映射导致堆栈溢出

    我正在尝试淘汰赛和映射插件 并想知道为什么这不起作用 我有一个要使用映射扩展加载的视图模型 function todoListViewModel data ko mapping fromJSON data todos TodoItem op
  • 为什么 PCRE 正则表达式比 C++11 正则表达式快得多

    一些示例代码 这是使用 cregex iterator 的 c 11 部分 std chrono steady clock time point begin0 std chrono steady clock now regex re
  • PHP 从表行中检索数据并将其存储到变量

    我想这些问题已经说明了一切 我的查询结果会生成与条件匹配的行 我想从每个表列中获取每个数据并将其放入一个变量中 getinfo select user firstname user middlename user lastname from
  • 在 Django 中上传文件

    我在 Django 1 6 版本 中上传文件时遇到问题 当我尝试做的时候new file data save 在我的views py 中我收到此错误 quiz patent 22 medical record 2 exams 处的属性错误
  • C++:创建一个由用户输入大小的数组

    我想知道我们是否可以创建一个具有用户指定大小的数组 Ex int a cout lt lt Enter desired size of the array cin gt gt a int array a 上面的程序将不起作用 因为数组大小必
  • 包含可变数据的正则表达式 - ply.lex

    我正在使用 python 模块ply lex编写一个词法分析器 我用正则表达式指定了一些标记 但现在我卡住了 我有一个list of Keywords谁应该是token data是一个包含大约 1000 个关键字的列表 这些关键字都应该被识
  • JQuery:检查元素是否处于正常流程中

    使用 jQuery 检查元素是否在正常流程中的最优雅的方法是什么 根据CSS3规范 http www w3 org TR css3 box 如果满足以下条件 则框属于流 其 display 的使用值为 block list item tab
  • 在 VS Code 中启动没有网络安全的 Chrome

    如何在没有网络安全的情况下配置 Chrome 浏览器launch jsonVS Code 中的文件 我安装了 VS Code 扩展Chrome 调试器我的 launch json 看起来是这样 version 0 2 0 configura
  • 私人消息数据库设计

    我正在创建一个简单的私人消息系统 但我不确定哪种数据库设计更好 第一个设计是一个消息表 以及一个消息评论表 Message id recipientId senderId title body created at MessageComme
  • 为什么虽然输入的值确实发生了变化,但jquery更改事件没有触发? [复制]

    这个问题在这里已经有答案了 JSFIDDLE http jsfiddle net meXm3 2 网页代码
  • 创建地图后向 Google 地图 v3 添加标记

    我对使用 Google Maps API 比较陌生 现在我正在开发一个项目 用户可以选择各种搜索过滤器并查看结果自动显示在地图上 而无需重新加载页面 到目前为止 我的方法是创建一个控制地图的 Javascript 对象 以便我可以按照我的意
  • Git 中的提交是越多越好还是越少越好? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我最近与一位同事进行了一场辩论 他坚持认为 由于合并冲突 提交越少越好 我认为通过使用尽可能多的提交获得的细节越多越好 提交更多还是更少更好 为
  • 如何获取AWS ec2中区域的可用容量?

    AWS 终止了我的运行位置 并出现错误 实例终止容量超额订阅 有没有办法查看不同 ec2 区域中实例类型的可用容量 这样我就可以在更 可用 的区域创建我的新位置 查看 现货实例历史记录 这不会告诉您未来 但会给您迄今为止的良好指示 此链接将
  • 如何在 groovy 中将输出重定向到 stderr?

    我正在寻找一种将 groovy 脚本中的输出重定向到 stderr 的方法 catch Exception e println Want this to go to stderr 就在我的脑海中 你不能做一些自我接线吗 def printE
  • Kafka REST 代理 API 有哪些好处?

    我不知道Kafka REST Proxy API的优点 它是一个 REST API 所以我知道它对于管理来说很方便 人们为什么使用 Kafka REST 代理 API 添加对生产者或消费者的 Maven 依赖是否很麻烦 另外 我知道kafk
  • Cordova Android 应用程序中的网页不可用

    编辑 我一直在解决这个问题并回顾我的所有步骤 我很乐意缩小这个问题的规模 并在令人困惑的情况下获得更多确切的细节 目前 我觉得 Keycloak 似乎只想将我重定向到 https 据我所知 这应该是 Wildfly 服务器配置问题 编辑 我
  • 无法在 PowerShell 中完全解析 XML

    我有一个 XML 文件 我想解析该文件并检索特定信息 为了便于理解 下面是 XML 文件的屏幕截图 我想解析 XML 并为每个Item节点 检索屏幕截图中指示的字段 检索到的每个值都需要针对每个项目节点进行格式化 最后 我希望能够指定一个要
  • Ctrl-退格键 Visual Studio 2010

    I recently upgraded to Visual Studio 2010 and found out that when I press Ctrl Backspace on an empty line it will delete
  • Python ttk.combobox 强制发布/打开

    我正在尝试扩展 ttk 组合框类以允许自动建议 我到目前为止的代码运行良好 但我想让它在输入一些文本后显示下拉列表 而不从小部件的输入部分移除焦点 我正在努力解决的部分是找到一种强制下拉的方法 在 python 文档中我找不到任何提及这一点