2016-09-29 52 views
0

我想點擊一個「面板」後,如何在 之後更新「狀態欄」的建議。wxhaskell:使用面板上的「點擊」更新狀態欄

下面的程序演示了這個問題。該程序繪製兩個 幀。你可以想象左邊框架是某種繪畫區域 ,右邊框架包含按鈕「紅色」和「綠色」。 點擊標有「紅色」的按鈕後,statusField的文本爲 已更新爲「當前顏色:紅色」。標有「綠色」的按鈕將文本更新爲「當前顏色:綠色」。

如何在用戶點擊 左側面板後更改statusField的文本?例如。將其更改爲「您成功點擊了 繪圖面板。」

爲什麼我不能在「on click」中按照與「on command」相同的方式爲 按鈕? (請參閱下面的源代碼註釋。)

非常感謝。

module Main where 

import Graphics.UI.WX 

-- | NOP (= No Operation) 
data Command = Nop 
      | Red 
      | Green 
       deriving (Eq) 

main :: IO() 
main 
    = start hello 


hello :: IO() 
hello 
    = do currentCommand <- varCreate $ Nop    -- current command performed on next click on "pDrawingarea" 

      status <- statusField [text := "Welcome."] 

      -- Frames and Panels 
      f   <- frame [ text := "Demo" 
            , bgcolor := lightgrey ] 

      pButtons  <- panel f [ bgcolor := lightgrey] 
      pDrawingarea <- panel f [ on paint := draw 
            , bgcolor := lightgrey 
            ] 

      set pDrawingarea [on click := do drawingAreaOnClick status currentCommand pDrawingarea 
              -- set status [text := "User clicked on the panel."] 
              -- Problem: uncommenting the line above shows the problem 
          ] 

      bRed <- button pButtons [text := "Red", on command := do varSet currentCommand Red 
                    set status [text := "Current color: Red"] 
           ] 

      bGreen <- button pButtons [text := "Green", on command := do varSet currentCommand Green 
                     set status [text := "Current color: Green"] 
            ] 

      set pButtons [ layout := column 1 [ hstretch.expand $ widget bRed 
              , hstretch.expand $ widget bGreen 
              ] 
         ] 

      set f [ statusBar := [status] 
       , layout := row 3 [ 
            minsize (sz 600 500) $ stretch.expand $ widget pDrawingarea 
            , vstretch.expand $ rule 3 500 
            , minsize (sz 200 500) $ vstretch.expand $ widget pButtons 
            ]  
       ] 

      return() 

draw :: DC a -> Rect -> IO() 
draw dc viewArea 
    = do putStrLn "Imagine some code to repaint the screen." 


drawingAreaOnClick :: statusField -> Var Command -> Panel() -> Point -> IO() 
drawingAreaOnClick sf command panel pt 
    = do c <- varGet command 
     case c of 
      Red -> do putStrLn "Imagine some code to do red painting" 
      Green -> do putStrLn "Imagine some code to do green painting" 

回答

0

在這個問題上花了很多時間之後,我發現了一個解決方案。

解決的辦法是的

drawingAreaOnClick :: statusField -> Var Command -> Panel() -> Point -> IO() 

的定義修改爲

drawingAreaOnClick :: Textual x => x -> Var Command -> Panel() -> Point -> IO() 

因爲「statusField」本身是類「考證」我不明白這個問題的一個成員。

爲了完整起見,我會提及我也轉換了GHC版本。最初的問題與GHC 7.8.4一起發生,我找到的解決方案與GHC 7.10.3一起工作。我不能說GHC版本是否會影響問題。

僅供參考完整的工作代碼:

module Main where 

import Graphics.UI.WX 

-- | NOP (= No Operation) 
data Command = Nop 
      | Red 
      | Green 
       deriving (Eq) 

main :: IO() 
main 
    = start hello 


hello :: IO() 
hello 
    = do currentCommand <- varCreate Nop    -- current command performed on next click on "pDrawingarea" 


      status <- statusField [text := "Welcome."] 

      -- not needed:  currentStatus <- varCreate status 


      -- Frames and Panels 
      f   <- frame [ text := "Demo" 
            , bgcolor := lightgrey ] 

      pButtons  <- panel f [ bgcolor := lightgrey] 
      pDrawingarea <- panel f [ on paint := draw 
            , bgcolor := lightgrey 
            ] 

      set pDrawingarea [on click := do drawingAreaOnClick status currentCommand pDrawingarea 
              -- set status [text := "User clicked on the panel."] 
              -- Problem: uncommenting the line above shows the problem 
          ] 

      bRed <- button pButtons [text := "Red", on command := do varSet currentCommand Red 
                    set status [text := "Current color: Red"] 
           ] 

      bGreen <- button pButtons [text := "Green", on command := do varSet currentCommand Green 
                     set status [text := "Current color: Green"] 
                     --sf <- varGet currentStatus 
                     -- set sf [text := "yyy"] 

            ] 

      set pButtons [ layout := column 1 [ hstretch.expand $ widget bRed 
              , hstretch.expand $ widget bGreen 
              ] 
         ] 

      set f [ statusBar := [status] 
       , layout := row 3 [ 
            minsize (sz 600 500) $ stretch.expand $ widget pDrawingarea 
            , vstretch.expand $ rule 3 500 
            , minsize (sz 200 500) $ vstretch.expand $ widget pButtons 
            ]  
       ] 

      return() 

draw :: DC a -> Rect -> IO() 
draw dc viewArea 
    = do putStrLn "Imagine some code to repaint the screen." 


drawingAreaOnClick :: Textual x => x -> Var Command -> Panel() -> Point -> IO() 
drawingAreaOnClick sf command panel pt 
    = do c <- varGet command 
     set sf [text := "Drawing on the screen."] 
     case c of 
      Red -> do putStrLn "Imagine some code to do red painting" 
      Green -> do putStrLn "Imagine some code to do green painting"