Search code examples
haskellgladegtk2hs

Is it possible to use menus created with Glade in gtk2hs?


I have menus created with Glade in my gtk2hs application. Is it possible to use this in my Haskell code to write actions for each activated menu item? Is there a simple example somewhere or project on Hackage that can be used as an illustrative example?

The only menu example I was able to find http://www.muitovar.com/gtk2hs/chap7-1.html does not seem to help to work with Gtk Builder XML.


Solution

  • Here two examples from an application of mine. In main, I bind the GTK widgets to variables and those to callback functions that I implement in other modules.

    --To load the Glade file:

    gui <- builderNew
    builderAddFromFile gui "myGUI.glade"
    

    -- To close the application:

    -- bind the window "mainWindow" (defined in the Glade file) to a variable

    mainWindow <- builderGetObject gui castToWindow "mainWindow"
    

    -- bind the menu item "menu_Quit" (defined in the Glade file) to a variable

    mQuit <- builderGetObject gui castToMenuItem "menu_Quit"
    

    -- bind the menu item to the GTK function "widgetDestroy"

    on mQuit menuItemActivate $ widgetDestroy mainWindow
    

    -- bind mainWindow's event "objectDestroy" to the GTK function "mainQuit"

    on mainWindow objectDestroy mainQuit
    

    -- To call a function when the user selects another menu item, say "menu_About":

    -- bind the menu item to a variable

    mAbout <- builderGetObject gui castToMenuItem "menu_About"
    

    -- make the menu item show the About Dialog (defined in the Glade file)

    on mAbout menuItemActivate $ do
        aboutDialog <- builderGetObject gui castToDialog "aboutDialog"
        set aboutDialog [ widgetVisible := True ]
        dialogRun aboutDialog
        set aboutDialog [ widgetVisible := False ]
    

    You could place the do block in a function, maybe in a module where you define all your responses to GTK events:

    showAboutDialog :: Builder -> IO ()
    showAboutDialog gui = [insert do block here]
    

    Then you could substitute the do block after menuItemActivate with just:

    on mAbout menuItemActivate $ showAboutDialog gui
    

    Note that I pass the Builder object to showAboutDialog because that function needs to get the dialog from the Glade file.