2012-02-21 120 views
4

我已經徹底搜索(至少我相信是這樣),我沒有找到任何問題的答案,所以我想問你的幫助。 我試圖確定何時用戶右鍵單擊我的treeView(用戶列表)中的一行,然後顯示一個彈出窗口,其中包含用於編輯和刪除它們的選項。在treeview行捕獲右鍵單擊事件[haskell gtk2hs]

Here's我的應用程序的外觀至今

下面是生成的TreeView代碼:

import Graphics.UI.Gtk 
import System.Glib.Signals (on) 
import Graphics.UI.Gtk.Glade 
import Graphics.UI.Gtk.ModelView as New 
import SzuDB 

data GUI = GUI { 
       mainWindow :: Window, 
       --Buttony 
       dodajUczBt :: Button, 
       cancelAddUczBt :: Button, 
       zapiszUczBtn :: Button, 
       --TreeView 
       listaUczView :: TreeView, 
       -- Dialogi 
       dodajUzDialog :: Dialog, 
       -- Entry 
       nImie :: Entry, 
       nNazwisko :: Entry, 
       nWiek :: SpinButton, 
       lblLiczbaUcz :: Label 

       } 

-- Różne listy 

data ListStores = ListStores { uczestnicy :: ListStore Uczestnik } 


main = do 
     initGUI 

     dbh <- connect "szu.db" 

     gui <- loadGlade "szu.glade" dbh 

     -- lapiemy uzytkownikow 
     uczestnicy <- getAllUsers dbh 

     labelSetText (lblLiczbaUcz gui) $ "Liczba uczestników: "++ show (length uczestnicy) 

     listaUczestnikow <- New.listStoreNew uczestnicy 
     New.treeViewSetModel (listaUczView gui) listaUczestnikow 
     wyswietlUczestnikow (listaUczView gui) listaUczestnikow 

     let liststore = ListStores $ listaUczestnikow 

     loadGUIEvents gui dbh liststore 


     widgetShowAll (mainWindow gui) 
     mainGUI 

--  loadGlade etc. 

wyswietlUczestnikow view uczestnik = do 
     New.treeViewSetHeadersVisible view True 

     -- add a couple columns 
     renderer1 <- New.cellRendererTextNew 
     col1 <- New.treeViewColumnNew 
     New.treeViewColumnPackStart col1 renderer1 True 
     New.cellLayoutSetAttributes col1 renderer1 uczestnik $ \row -> [ New.cellText := imie row ] 
     New.treeViewColumnSetTitle col1 "Imię" 
     New.treeViewAppendColumn view col1 

     renderer2 <- New.cellRendererTextNew 
     col2 <- New.treeViewColumnNew 
     New.treeViewColumnPackStart col2 renderer2 True 
     New.cellLayoutSetAttributes col2 renderer2 uczestnik $ \row -> [ New.cellText := nazwisko row ] 
     New.treeViewColumnSetTitle col2 "Nazwisko" 
     New.treeViewAppendColumn view col2 

     renderer3 <- New.cellRendererTextNew 
     col3 <- New.treeViewColumnNew 
     New.treeViewColumnPackStart col3 renderer3 True 
     New.cellLayoutSetAttributes col3 renderer3 uczestnik $ \row -> [ New.cellText := show (wiek row) ] 
     New.treeViewColumnSetTitle col3 "Wiek" 
     New.treeViewAppendColumn view col3 

-- 
-- ladujemy wydarzenia 
-- 

-- loadGuiEvents etc. 

我已經嘗試使用在http://www.muitovar.com/gtk2hs/chap7-2.html的例子,但它導致編譯錯誤(有人說, eventButton與一個參數一起使用,而它不需要)。

任何幫助,將不勝感激:) 乾杯

回答

4

好吧,似乎我會去尋找答案我自己的問題:)

(1)所有的例子首先第一個在http://www.muitovar.com/gtk2hs/chap7-2.html不適用於我,因爲您在gtk2hs中有兩個eventButton函數,您必須使用Graphics.UI.Gtk.Gdk.Events中的函數。所以,你必須在文件的開頭添加:

import Graphics.UI.Gtk.Gdk.Events as Ev 

,然後添加Ev.前綴eventButtonRightButtoneventSent。現在將工作:)

(2)如何應對上的TreeView排右點擊:已經解決了,我偶然發現this例如,當它展示瞭如何在選擇行迴應上述問題

樹視圖。所以,我是混合這兩種解決方案,並與像這樣(大部分代碼來自樹狀例如我的一些調整的)想出了:

module Main where 

{- an example how to select from a list 
    not satisfactory yet: 
     - there should be a simpler way to render a simple list 
     - i could not convert the model i got back to a list 
      from which to get the value 

     - the interface offers a great number of functions 
      and it is very difficult to find which ones are 
      really needed for simple tasks 
    -} 

import Graphics.UI.Gtk 
import Graphics.UI.Gtk.ModelView as Model 
import Graphics.UI.Gtk.Gdk.Events as Ev 

main :: IO() 
main = do 
    initGUI  -- is start 
    window <- windowNew 

    list <- listStoreNew ["Vince", "Jhen", "Chris", "Sharon"] 

    treeview <- Model.treeViewNewWithModel list 
    Model.treeViewSetHeadersVisible treeview True 

      -- there should be a simpler way to render a list as the following! 
    col <- Model.treeViewColumnNew 
    Model.treeViewColumnSetTitle col "colTitle" 
    renderer <- Model.cellRendererTextNew 
    Model.cellLayoutPackStart col renderer False 
    Model.cellLayoutSetAttributes col renderer list 
      $ \ind -> [Model.cellText := ind] 
    Model.treeViewAppendColumn treeview col 

    --tree <- Model.treeViewGetSelection treeview 
    --Model.treeSelectionSetMode tree SelectionSingle 
    --Model.onSelectionChanged tree (oneSelection list tree) 

    set window [ windowDefaultWidth := 100 
       , windowDefaultHeight := 200 
       , containerChild := treeview 
       ] 

    -- here comes the right-click popup  

    eda <- actionNew "EDA" "Edit" Nothing Nothing 
    pra <- actionNew "PRA" "Process" Nothing Nothing 
    rma <- actionNew "RMA" "Remove" Nothing Nothing 
    saa <- actionNew "SAA" "Save" Nothing Nothing 

    agr <- actionGroupNew "AGR1" 
    mapM_ (actionGroupAddAction agr) [eda,pra,rma,saa] 

    uiman <- uiManagerNew 
    uiManagerAddUiFromString uiman uiDecl 
    uiManagerInsertActionGroup uiman agr 0 

    maybePopup <- uiManagerGetWidget uiman "/ui/popup" 
    let pop = case maybePopup of 
      (Just x) -> x 
      Nothing -> error "Cannot get popup from string" 

    onButtonPress treeview (\x -> if (Ev.eventButton x) == Ev.RightButton 
           then do 
           menuPopup (castToMenu pop) Nothing 
           return (Ev.eventSent x) 
           else return (Ev.eventSent x)) 

    mapM_ (prAct treeview list) [eda,pra,rma,saa]  


    onDestroy window mainQuit 
    widgetShowAll window 
    mainGUI 
    return() 

uiDecl = "<ui> \ 
\   <popup>\ 
\   <menuitem action=\"EDA\" />\ 
\   <menuitem action=\"PRA\" />\ 
\   <menuitem action=\"RMA\" />\ 
\   <separator />\ 
\   <menuitem action=\"SAA\" />\ 
\   </popup>\ 
\  </ui>" 

-- Handle the right-click. You can write a function that'll respond to various 
-- actions, like for example: handleAction "EDA" = do something, etc.  

prAct treeview list a = onActionActivate a $ do 
     name <- actionGetName a 
      -- getting the selected row 

     tree <- Model.treeViewGetSelection treeview 

     -- you can also use treeSelectionGetSelected to get the Iter object 
      -- and then convert it to Int by using listStoreIterToIndex and so get 
      -- the ListStore item at given index 

      sel <- Model.treeSelectionGetSelectedRows tree 
     let s = head (head sel) 
     v <- Model.listStoreGetValue list s 
     putStrLn ("Action Name: " ++ name ++ " | Item: " ++ v) 

我希望這將是爲別人有用:)

乾杯