Erfassen eines Rechtsklick-Ereignisses in einer Baumansichtszeile [haskell gtk2hs]
-
28-10-2019 - |
Frage
Ich habe gründlich gesucht (zumindest glaube ich das) und keine Antwort auf mein Problem gefunden. Deshalb möchte ich Sie um Hilfe bitten. Ich versuche festzustellen, wann ein Benutzer mit der rechten Maustaste auf eine Zeile in meiner Baumansicht (Liste der Benutzer) klickt, und dann ein Popup-Fenster mit Optionen zum Bearbeiten und Löschen anzuzeigen.
Ich habe bereits versucht, das Beispiel unter http://www.muitovar.com zu verwenden/gtk2hs/chap7-2.html führte jedoch zu einem Kompilierungsfehler (eventButton wird mit einem Argument verwendet, während keines erforderlich ist).
Jede Hilfe wäre sehr dankbar :) Prost
Lösung
Okay, es scheint, ich werde der erste sein, der eine Antwort auf meine eigene Frage findet :)
(1) Zunächst das Beispiel unter http://www.muitovar.com /gtk2hs/chap7-2.html hat bei mir nicht funktioniert, da Sie in gtk2hs zwei eventButton
-Funktionen haben und die aus Graphics.UI.Gtk.Gdk.Events
verwenden müssen. Sie müssen also am Anfang der Datei Folgendes hinzufügen:
import Graphics.UI.Gtk.Gdk.Events as Ev
und fügen Sie dann das Präfix Ev.
zu eventButton
, RightButton
und eventSent
hinzu. Es wird jetzt funktionieren :)
(2) So reagieren Sie auf Rechtsklicks auf die treeView-Zeile:
Nachdem ich das oben genannte Problem gelöst hatte, stieß ich auf dieses Beispiel, in dem es gezeigt wird So reagieren Sie auf die Auswahl einer Zeile in treeView. Also habe ich diese beiden Lösungen gemischt und mir so etwas ausgedacht (der größte Teil des Codes stammt aus dem Treeview-Beispiel mit einigen meiner Optimierungen):
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)
Ich hoffe, es ist hilfreich für jemanden :)
Prost