首页 > 解决方案 > tkinter 对话框突出显示父条目文本

问题描述

我试图复制 Python Idle 的 Search Dialog 的行为,它突出显示后面的文本。所以我参考这个链接并制作我自己的对话:http ://effbot.org/tkinterbook/tkinter-dialog-windows.htm

Python 空闲搜索对话框

问题是self.grab_set(),我无法突出显示调用对话框的父窗口的文本。我不想删除,self.grab_set()因为我也不希望用户在搜索时四处点击。

正如我在对话框的其他实现中测试的那样,按钮的 onclick 侦听器被正确执行。例如,使用替换对话框正确替换文本。所以唯一的问题是父窗口中的条目文本没有突出显示/选择。实际上,如果我删除文本可以突出显示self.grab_set()。但是,对话框失去焦点,一旦我这样做,焦点就会转到父窗​​口的条目。而且我无法按 Enter 键在对话框中查找下一个。

我该如何解决这个问题?提前致谢!

我的实现

- -更新 - -

测试代码可以非常简单,如下所示。

from tkinter import *

SYSTEM_HIGHLIGHT = 'SystemHighlight'
BUTTON_BORDER = '#b5b5b5'
class FindDialog(Toplevel):
    def __init__(self, master):
        Toplevel.__init__(self, master)
        self.master = master
        self.transient(master)
        self.grab_set()
        self.geometry("+%d+%d" % (master.winfo_rootx() + 50, master.winfo_rooty() + 50))
        self.title('Search Dialog')

        ## Variables
        self.findListner = None

        self.findLabel = Label(self, text = 'Find:')
        self.findEntry = Entry(self)
        self.findEntry.focus()
        self.findEntry.select_range(0, END)
        for i, w in enumerate([self.findLabel, self.findEntry]):
            w.grid(row = 0, column = i, sticky = NSEW)
        self.findEntry.grid(columnspan = 5)
        self.findButton = Button(self, text = 'Find Next', command = self.find)
        self.findButton.grid(row = 1, column = i + 1, sticky = NSEW)
        self.bind('<Return>', lambda event: self.find())

    def setOnFindListner(self, listener):
        '''listner should have the following arguments: dialog, target, direction.'''
        self.findListner = listener

    def find(self):
        if not self.findListner: return
        self.findListner(self, self.findEntry.get())

def find():
    dialog = FindDialog(root)
    dialog.setOnFindListner(onFind)
    root.wait_window(dialog)

def onFind(*args):
    e.focus_set()
    e.select_range(0, END)
    e.icursor(END)

root = Tk()
e = Entry(root)
e.pack()
e.focus()
e.insert(0, 'HelloWorld')
root.bind('<Control-f>', lambda event: find())
root.mainloop()

标签: pythonpython-3.xtkintertkinter-entrypython-3.7

解决方案


条目小部件的设计使得只有一个小部件可以具有焦点,并且只有焦点小部件的选择可见。如果没有这个,很容易创建一个用户界面,用户将无法知道键盘事件会去哪里,或者复制事件会复制什么。这可能并非在所有平台上都是如此,但自从我在除 mac 之外的任何东西上工作以来已经有一段时间了。

如果您的系统允许多个条目小部件显示一个选择,您可以通过确保将exportselection所有条目小部件的选项设置为 false 来解决问题。如果您试图突出显示的小部件是一个Text小部件,那就足够了。从您的问题中不清楚您是否真的需要搜索Text小部件或Entry小部件,这种区别很重要。

可以说更好的解决方案是使用文本小部件和您自己的自定义标签而不是选择,因为您自己的标签不会有这些限制。您可以使标签看起来与选择相同,或者您可以给它一个不同的外观,以便清楚突出显示的代码具有与用户手动选择的代码不同的行为。


推荐阅读