Michael Mossey wrote: > Duncan Coutts wrote: >> On Wed, 2009-09-09 at 18:29 -0700, Michael P Mossey wrote: >>> I'm trying to learn qtHaskell. I realize few people on this list >>> know anything about qtHaskell, but I have a question that probably >>> relates to all GUIs as implemented in Haskell. I just need a hint >>> that could help me figure out the next step, which I might be able >>> to infer from the qtHaskell API. >> >> Ultimately it's done by some kind of mutable state, either an IORef, >> MVar or a thread. In wxHaskell, the 'simplest' way to code this looks something like the following (literate Haskell)
Structure containing 'state' of all of the GUI objects > data UIState = UIState { uiConnect :: Button () > , uiPort :: TextCtrl () > , uiUser :: TextCtrl () > , uiPasswd :: TextCtrl () > , uiSandbox :: TextCtrl () > , uiClients :: ComboBox () > , uiChanges :: SingleListBox () > , uiChangeInfo :: TextCtrl () > , uiOrigin :: TextCtrl () > , uiUpdate :: TextCtrl () > , uiFrame :: Frame () > } > uiState = unsafePerformIO $ newMVar (Nothing :: Maybe UIState) Ensure that we initialize exactly once... > uiInitState bt pt us pw sb cl ci ch or up f = > takeMVar uiState >>= \st -> > case st of > Nothing -> let st' = UIState bt pt us pw sb cl ci ch or up f in > putMVar uiState (Just st') > Just _ -> return () Get the mutable state. Note that in the error case we deliberately do not put the MVar back, as a means to block all threads waiting on the MVar (as this would indicate a general programming/threading issue to be identified). > getMVarState mv txt = > takeMVar mv >>= \may_st -> > case may_st of > Nothing -> error (txt ++ " is not available") > Just st -> putMVar mv may_st >> > return st Fetch the UI state - this will fail fatally if we fetch before state is initialized > uiGetState = getMVarState uiState "UI state" I don't have anything as neat to show you as Duncan's suggetion (I'd also be interested to see a cleaner way to do it - this sort of code always grates a little with me, although all of the major Haskell GUI bindings seem to need a similar programming style. However, at the most basic 'trying it out' level, I suspect that something very like this will work just as well for qtHaskell as it does for wxHaskell. >> On top of these you can layer nicer stuff like a state monad (with a >> 'runState' function that saves and restores from an IORef). >> >> A personal favourite of mine is having the GUI event handler post data >> over a channel to a thread. That thread reads from the channel and deals >> with the events. The state of the GUI app is then held as local >> parameters in that thread. >> >> Doing this of course requires that the GUI lib you're using can cope >> with normal Haskell (forkIO) threads. This is possible with gtk2hs, I >> don't know about the others. Regards Jeremy
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe