【问题标题】:gtk : combo of pictures in a treeviewgtk : 树视图中的图片组合
【发布时间】:2015-01-31 11:37:00
【问题描述】:

我正在尝试在树视图单元格内制作一个图片组合框(如下所示)以进行选择。

我尝试使用cellRendererComboNew 来渲染组合,但填充组合框cellComboTextModel := 的选项仅适用于String,我无法渲染图片。

我尝试使用cellRendererPixbufNew。它渲染图像,但我无法对其执行选择。

这样做的正确方法是什么?

Haskell、Python 或任何语言的示例都会很有帮助。

最好的问候。

【问题讨论】:

    标签: haskell combobox treeview gtk gtk2hs


    【解决方案1】:

    在 PyGobject 中,我想出了这个解决方案。该示例功能齐全,但需要在同一目录中有 2 个 png 文件。我使用了两个 100 x 20 像素格式的 png。

    前面的例子使用了 Gtk.ComboBox.new_with_model_and_entry() 并且我缺少了 set_entry_text_colum() 函数,它必须与这种组合框一起使用。

    #!/usr/bin/python3
    
    from gi.repository import Gtk, Gdk, GdkPixbuf
    
    class ComboBoxWindow(Gtk.Window):
    
        def __init__(self):
            Gtk.Window.__init__(self, title="ComboBox Pixbuf Example")
    
            self.set_border_width(10)
    
            store = Gtk.ListStore(str, GdkPixbuf.Pixbuf)
            solid_line = GdkPixbuf.Pixbuf.new_from_file("solid_line.png")
            store.append(["1", solid_line])
            dashed_line = GdkPixbuf.Pixbuf.new_from_file("dashed_line.png")
            store.append(["2", dashed_line])
    
            vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
    
            combo = Gtk.ComboBox.new_with_model(store)
            rend_int = Gtk.CellRendererText()
            rend_pixbuf = Gtk.CellRendererPixbuf()
            combo.pack_start(rend_int, False)
            combo.add_attribute(rend_int, "text", 0)
            combo.pack_start(rend_pixbuf, True)
            combo.add_attribute(rend_pixbuf, "pixbuf", 1)
            combo.connect("changed", self.on_combo_changed)
    
            vbox.pack_start(combo, False, False, 0)
    
            self.add(vbox)
    
        def on_combo_changed(self, combo):
            tree_iter = combo.get_active_iter()
            if tree_iter != None:
                model = combo.get_model()
                row = model[tree_iter][0]
                print("Selected row {0}".format(row))
    
    win = ComboBoxWindow()
    win.connect("delete-event", Gtk.main_quit)
    win.show_all()
    Gtk.main()
    

    类似的问题:

    来源:

    【讨论】:

    【解决方案2】:

    这是我在 Haskell 中的解决方案:

    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE OverloadedStrings #-}
    
    import Data.String
    import Graphics.UI.Gtk
    import qualified Data.Map as Map
    import qualified Data.Text as T
    import Data.Maybe
    import qualified Graphics.UI.Gtk.Gdk.Pixbuf as Pixbuf
    import Control.Monad
    
    colorsRawL = [(0,0,0),(254,26,89),(255,0,0),(0,255,0),(0,0,255),(255,255,0),(0,255,255),(255,0,255),(192,192,192),(128,128,128),(128,0,0),(128,128,0),(0,128,0),(128,0,128),(0,128,128),(0,0,128)]
    manufacturers = [("Sony"::String), ("LG"::String), ("Panasonic"::String), ("Toshiba"::String), ("Nokia"::String), ("Samsung"::String)]
    
    data ListElement = ListElement { name :: String   ,   selected::Pixbuf  }
    
    getManufacturers::IO[ListElement]
    getManufacturers = mapM (\x -> do 
                                 pbn <- Pixbuf.pixbufNew ColorspaceRgb False 8 16 16
                                 Pixbuf.pixbufFill pbn 255 255 255 1 
                                 let el = ListElement x pbn
                                 return el                            
                               ) manufacturers
         
    pixBufListS::IO [(String,Pixbuf)]
    pixBufListS =   mapM (\(r,g,b)-> do 
                                 pbn <- Pixbuf.pixbufNew ColorspaceRgb False 8 16 16
                                 Pixbuf.pixbufFill pbn r g b 1 
                                 let name::String = ("Color ("++(show r)++" "++(show g)++" "++(show b)++  ")")                             
                                 return (name,pbn)                            
                               ) colorsRawL
    
    getMap::IO (Map.Map String Pixbuf)
    getMap = do
        list <- pixBufListS
        let mp = Map.fromList list
        return mp
    
    main :: IO ()   
    main = do    
        initGUI
        window  <- windowNew
        fixed <- fixedNew
        
        pixList <-pixBufListS
    
        manus <- getManufacturers
        lststoreManus::(ListStore ListElement) <- listStoreNew manus
    
        treeview <- treeViewNew
        treeViewSetModel treeview lststoreManus
        treeViewSetHeadersVisible treeview True
    
        colName <- treeViewColumnNew
        imgCol <- treeViewColumnNew
        colCombo <- treeViewColumnNew
        treeViewColumnSetTitle imgCol ("Image column"::T.Text  )
        treeViewColumnSetTitle colName ("String column"::T.Text  )
        treeViewColumnSetTitle colCombo ("Combo"::T.Text  )
    
        iconRenderer <- cellRendererPixbufNew
        renderer1 <- cellRendererTextNew
        comboRenderer <- cellRendererComboNew
    
        cellLayoutPackStart imgCol iconRenderer True
        cellLayoutPackStart colName renderer1 True
        cellLayoutPackStart colCombo comboRenderer True
        
        cellLayoutSetAttributes imgCol iconRenderer lststoreManus $  (\ListElement { selected = t } -> [cellPixbuf := t])
        cellLayoutSetAttributes colName renderer1 lststoreManus $ \row -> [ cellText := name row ]
    
        cellLayoutSetAttributeFunc colCombo comboRenderer lststoreManus $ 
            (\iter -> do (tmodel, colid) <- comboTextModel 
                         (ListElement a b) <- treeModelGetRow lststoreManus iter
                         set comboRenderer [ cellVisible        := True
                                           , cellComboTextModel := (tmodel, colid)
                                           , cellTextEditable   := True
                                           , cellComboHasEntry  := False
                                           , cellText           := ("Choose pixbuf"::String)])  
    
        treeViewAppendColumn treeview colName
        treeViewAppendColumn treeview imgCol
        treeViewAppendColumn treeview colCombo
    
        _ <- on comboRenderer editingStarted $ \widget treepath -> do
         case treepath of
          [k] -> do       
            let comboPix::ComboBox = castToComboBox widget
            
            lststorerep::(ListStore (String,Pixbuf)) <- listStoreNew pixList
            customStoreSetColumn lststorerep (makeColumnIdString 0) fst
            customStoreSetColumn lststorerep (makeColumnIdPixbuf 1) snd
          
            comboBoxSetModel comboPix (Just lststorerep)
            rendertxt <- cellRendererTextNew
            renderpic <- cellRendererPixbufNew
         
            cellLayoutPackStart  comboPix rendertxt False
            cellLayoutPackStart  comboPix renderpic True
            cellLayoutAddColumnAttribute comboPix renderpic cellPixbuf $ makeColumnIdPixbuf 1
           
        _ <- on comboRenderer edited $ \_treePath newStringValue -> do
            case _treePath of
              [k] -> do
               (ListElement a b) <- listStoreGetValue lststoreManus k
               myMap <- getMap
               let finded = fromJust ( Map.lookup newStringValue myMap  )
               let toStore = ListElement a finded
               listStoreSetValue lststoreManus k toStore
               putStrLn $ "new value: " ++ newStringValue  
       
        fixedPut fixed treeview (10,10)
        widgetSetSizeRequest  treeview 500 100
    
        containerAdd window fixed
        onDestroy window mainQuit
        windowSetDefaultSize window 600 500
        windowSetPosition window WinPosCenter
        widgetShowAll window
        mainGUI
    
    comboTextModel = do store <- listStoreNew []
                        let column = makeColumnIdString 0 :: ColumnId String String
                        return (store, column)
    
    {-
    dependencies :
    - base >= 4.7 && < 5
    - gtk
    - text
    - containers
    -}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多