PyGTK自定义ComboBox行为

时间:2011-03-02 20:18:03

标签: python list combobox coding-style gtk

我正在尝试创建一个行为类似于此处的自定义ComboBox:http://chir.ag/projects/name-that-color/

我现在有两个问题:

  1. 我似乎无法找到一种在侧面有滚动条的方法; gtk.rc_parse_string函数应该这样做,因为ComboBox小部件有一个“按列表显示”样式属性,但我的自定义小部件似乎不会因某些原因受到影响。

  2. 当您从我的窗口小部件中选择颜色,然后再次单击组合框,而不是显示所选项目及其邻居,滚动窗口从顶部开始,没有明显的原因。

  3. 这是代码,您几乎可以忽略__load_name_palette方法。您需要/usr/share/X11/rgb.txt文件来运行此代码,它看起来像这样:http://pastebin.com/raw.php?i=dkemmEdr

    import gtk
    import gobject
    from os.path import exists
    
    def window_delete_event(*args):
       return False
    
    def window_destroy(*args):
        gtk.main_quit()
    
    class ColorName(gtk.ComboBox):
        colors = []
        def __init__(self, name_palette_path, wrap_width=1):
            gtk.ComboBox.__init__(self)
            liststore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING,
                                     gobject.TYPE_STRING)
            name_palette = self.__load_name_palette(name_palette_path)
            for c in name_palette:
                r, g, b, name = c
                if ((r + g + b) / 3.) < 128.:
                    fg = '#DDDDDD'
                else:
                    fg = '#222222'
                bg = "#%02X%02X%02X" % (r, g, b)
                liststore.append((name, bg, fg))
    
            self.set_model(liststore)
            label = gtk.CellRendererText()
            self.pack_start(label, True)
            self.set_attributes(label, background=1, foreground=2, text=0)
            self.set_wrap_width(wrap_width)
    
            if len(name_palette) > 0:
                self.set_active(0)
            self.show_all()
    
        def __load_name_palette(self, name_palette_path):
            if exists(name_palette_path):
                try:
                    f = open(name_palette_path,'r')
                    self.colors = []
                    palette = set()
                    for l in f:
                        foo = l.rstrip().split(None,3)
                        try:
                            rgb = [int(x) for x in foo[:3]]
                            name, = foo[3:]
                        except:
                            continue
                        k = ':'.join(foo[:3])
                        if k not in palette:
                            palette.add(k)
                            self.colors.append(rgb + [name])
                    f.close()
                    return self.colors
                except IOError as (errno, strerror):
                    print "error: failed to open {0}: {1}".format(name_palette_path, strerror)
                    return []
                else:
                    return []
    
    if __name__ == '__main__':
        win = gtk.Window()
        #colname = ColorName('./ntc.txt')
        colname = ColorName('/usr/share/X11/rgb.txt')
        gtk.rc_parse_string("""style "mystyle" { GtkComboBox::appears-as-list = 1 }
        class "GtkComboBox" style "mystyle" """)
        print 'appears-as-list:', colname.style_get_property('appears-as-list')
        model = gtk.ListStore(gobject.TYPE_STRING)
        hbox = gtk.HBox()
        win.add(hbox)
        hbox.pack_start(colname)
        win.connect('delete-event', window_delete_event)
        win.connect('destroy', window_destroy)
        win.show_all()
        gtk.main()
    

1 个答案:

答案 0 :(得分:1)

问题是self.show_all()行。此外,您不能拥有列表和wrap_width!= 1