如何从gtk.Entry的图标创建下拉列表?

时间:2015-06-08 09:14:11

标签: pygtk

我有一个gtk.Entry,文本后面有一个图标,打算成为一个文本搜索字段:

gtk.Entry for search

我要做的是在用户点击图标时显示下拉列表(即gtk.ComboBox),以选择搜索类型。该功能的模拟将是:

Mock of gtk.Entry with icon ComboBox

我尝试了几件事但没有成功。例如,尝试打包一个空的gtk.ComboBox,只在Entry之后显示一个箭头,并将其填充到icon-press上,这会产生错觉,但它有两个缺点:a)当我填充ComboBox时,工具栏当我清除()ListStore时,ComboBox保留其宽度并留下一个丑陋的灰色框。

此时我想我需要在icon-press上创建一个CellRenderer,弹出Entry的图标,我试着理解gtk.ComboBoxEntry的代码(在{{3}中)没有太多成功}),但据我所知,它与CellRenderer一起使用整个棋子上的垂直容器。

GTK + 3在这方面也没有任何想法。

有关如何在PyGTK中创建此内容的任何想法或指导吗?

2 个答案:

答案 0 :(得分:1)

我正在寻找类似的东西,所以我想出了下面的代码。我还没有真正担心美学。我确实将一个元组列表传递给MyPopup类,并为下拉列表中的每个菜单项传递处理程序。请注意,item.show()是必要的,即使有show_all()

from gi.repository import Gtk

class MyPopup(Gtk.MenuButton):
    def __init__(self, btndefs):
        super(MyPopup, self).__init__()

        self.menu = Gtk.Menu()
        self.set_popup(self.menu)
        #self.set_label(">")
        self.set_direction(Gtk.ArrowType.RIGHT)

        for btndef in btndefs:
            item = Gtk.MenuItem()
            item.set_label(btndef[0])
            item.show()
            self.menu.append(item)

class MainWindow(Gtk.Window):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.set_size_request(100, -1)
        self.connect("destroy", lambda x: Gtk.main_quit())

        self.hbox = Gtk.Box(orientation = Gtk.Orientation.HORIZONTAL)
        self.entry = Gtk.Entry()

        self.popup = MyPopup( (("String",),
                               ("String no case",),
                               ("Hexadecimal",),
                               ("Regexp",)) )

        self.hbox.pack_start(self.entry, True, True, 0)
        self.hbox.pack_start(self.popup, False, True, 0)

        self.add(self.hbox)

        self.show_all()

    def run(self):
        Gtk.main()


def main():
    mw = MainWindow()
    mw.run()
    return 0

if __name__ == '__main__':
    main()

enter image description here

答案 1 :(得分:1)

是的,这一年晚了,但是不要让下一个人在这里偶然发现像我一样伤心

这是使用 Gtk.Menu() 弹出的示例,您也可以使用类似的功能。使用 Gtk.Popover()

enter image description here

#!/usr/bin/env python3

import gi
gi.require_version('Gtk', '3.0')

from gi.repository import Gtk, Gdk

opts = {
    'hex'     : "system-run-symbolic",
    'regex'   : "font-select-symbolic",
    'string'  : "font-x-generic-symbolic",
    'no-case' : "tools-check-spelling-symbolic",
}

def make_menu(entry, opts):
    menu = Gtk.Menu()
    for label, icon in opts.items():
        item = Gtk.MenuItem()
        item.set_label(label)
        item.connect(
            "activate",
            lambda w: entry.set_icon_from_icon_name(0, opts[w.get_label()])
        )
        menu.append(item)

        # NOTE you can use Gtk.ImageMenuItem to add image but its
        # Deprecated since version 3.10

    menu.show_all()
    return menu


def on_icon_release(widget, pos, event):
    menu = make_menu(widget, opts)
    menu.popup(
        parent_menu_shell = None,
        parent_menu_item  = None,
        func              = None,
        data              = None,
        button            = Gdk.BUTTON_PRIMARY,
        activate_time     = event.get_time()
    )

def make_entry():
    entry = Gtk.Entry()
    entry.set_icon_from_icon_name(0, 'action-unavailable-symbolic')
    entry.set_icon_from_icon_name(1, 'fonts')
    entry.set_icon_sensitive(1, True)
    entry.set_icon_activatable(1, True)
    entry.connect("icon-release", on_icon_release)
    return entry


root = Gtk.Window()
root.add(make_entry())
root.show_all()
Gtk.main()