如何使用“放大镜”图像和其中的一些文本创建搜索框

时间:2015-10-10 03:01:04

标签: user-interface python-3.x tkinter uisearchbar ttk

我想在Python 3中创建一个搜索框。我知道条目小部件和按钮,但我只想要像this这样更优雅的东西。甚至可以创建更接近图像中的东西的东西吗?如果是的话,请关注这个话题。 TIA

1 个答案:

答案 0 :(得分:1)

如果您使用搜索图标的图像创建新元素,则可以使用ttk执行此操作,您可以使用以下代码将其嵌入到文本窗口小部件中。在这种情况下,我们添加了一个主题' pin'图标,但这个元素可以很容易地替换。该演示看起来像这样,顶部的原始条目和下面的新样式:

example image

vsapi元素引擎仅在Windows上可用,但通过使用图像元素引擎来定义自定义元素,这将适用于所有Tk平台。

import tkinter as tk
import tkinter.ttk as ttk

class SearchEntry(ttk.Widget):
    """
    Customized version of a ttk Entry widget with an element included in the
    text field. Custom elements can be created using either the vsapi engine
    to obtain system theme provided elements (like the pin used here) or by using
    the "image" element engine to create an element using Tk images.

    Note: this class needs to be registered with the Tk interpreter before it gets
    used by calling the "register" static method.
    """
    def __init__(self, master, **kw):
        kw["style"] = "Search.Entry"
        ttk.Widget.__init__(self, master, 'ttk::entry', kw)
    def get(self):
        return self.tk.call(self._w, 'get')
    def set(self, value):
        self.tk.call(self._w, 'set', value)
    @staticmethod
    def register(root):
        style = ttk.Style()
        # There seems to be some argument parsing bug in tkinter.ttk so cheat and eval
        # the raw Tcl code to add the vsapi element for a pin.
        root.eval('''ttk::style element create pin vsapi EXPLORERBAR 3 {
            {pressed !selected} 3
            {active !selected} 2
            {pressed selected} 6
            {active selected} 5
            {selected} 4
            {} 1
        }''')
        #style.element_create("pin", "vsapi", "EXPLORERBAR", "3", [(["selected"], 4),([], 1)])
        style.layout("Search.Entry", [
            ("Search.Entry.field", {'sticky': 'nswe', 'children': [
                ("Search.Entry.background", {'sticky':'nswe', 'children': [
                    ("Search.Entry.padding", {'sticky':'nswe', 'children': [
                        ("Search.Entry.textarea", {'sticky':'nswe'})
                    ]})
                ]}),
                ("Search.Entry.pin", {'sticky': 'e'})
            ]})
        ])
        style.configure("Search.Entry", padding=(1, 1, 14, 1))
        style.map("Search.Entry", **style.map("TEntry"))

if __name__ == '__main__':
    root = tk.Tk()
    text = tk.StringVar()
    SearchEntry.register(root)
    frame = ttk.Frame(root)
    text.set("some example text ...")
    e1 = ttk.Entry(frame, textvariable=text)
    e2 = SearchEntry(frame, textvariable=text)
    e1.grid(sticky="news", padx=2, pady=2)
    e2.grid(sticky="news", padx=2, pady=2)
    frame.grid(sticky = "news", padx=2, pady=2)
    root.grid_columnconfigure(0, weight = "1")
    root.grid_rowconfigure(0, weight = "1")
    root.mainloop()