user-interface - 在 TreeView 行上捕获右键单击事件 [haskell gtk2hs]

标签 user-interface haskell glade right-click gtk2hs

我已经彻底搜索了(至少我相信是这样),但我没有找到任何解决我的问题的答案,所以我想向您寻求帮助。
我试图确定用户何时右键单击我的 treeView(用户列表)中的一行,然后显示一个带有编辑和删除选项的弹出窗口。

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 与一个参数一起使用,而它不需要)。

任何帮助将不胜感激 :)
干杯

最佳答案

好吧,看来我将成为第一个为我自己的问题找到答案的人:)

(1) 首先是http://www.muitovar.com/gtk2hs/chap7-2.html的例子对我不起作用,因为你有两个 eventButton gtk2hs 中的函数,您必须使用 Graphics.UI.Gtk.Gdk.Events 中的函数.所以你必须在文件的开头添加:

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

然后添加 Ev. eventButton的前缀, RightButtoneventSent .它现在可以工作了:)

(2)如何响应treeView行上的右键单击:

解决了上述问题后,我偶然发现了 this例如,它展示了如何响应在 treeView 中选择一行。所以我混合了这两个解决方案并想出了这样的东西(大部分代码来自 TreeView 示例,并进行了一些调整):
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)

我希望它会对某人有所帮助:)

干杯

关于user-interface - 在 TreeView 行上捕获右键单击事件 [haskell gtk2hs],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9383878/

相关文章:

ios - 一个 ViewController 中的多个 View

c# - 我应该使用什么组件来显示启用/禁用状态?

Haskell - 维护全局变量的不同状态

haskell - 尝试用 Haskell 求 GCD。我的代码错误在哪里?

c - Glade3 C 编程按钮

jquery UI 图标问题

ios - 同一 View Controller 的 UI 的多种变体

haskell - ReadP 中的 "count 3"解析了 3 次。如何解析出现 3 到 8 次的情况?

c - 从 *gint 到 gdouble gtk

python - PyGTK TreeView 中的粗体/非粗体行