2010-11-05 81 views
1

我想製作一個haskell程序,在窗口中繪製一些形狀。當我在窗口內點擊時,形狀的顏色應該改變。Haskell,在鼠標單擊時更改繪製顏色

我想出了這一點:

testDemo points = 
runGraphics $ 
    do 
     w <- openWindow "Test" (480, 550) 
     colorRef <- newIORef Green 
     let 
      loop0 = do 
         color <- readIORef colorRef 
         e <- getWindowEvent w 
         case e of 
          Button {pt=pt, isDown=isDown} 
           | isDown && color == Green -> writeIORef colorRef Red 
           | isDown && color == Red -> writeIORef colorRef Green 
          _ -> return() 
         color <- readIORef colorRef 
         drawInWindow w (withColor color (polyline points)) 
         loop0 

     color <- readIORef colorRef 
     drawInWindow w (withColor color (polyline points)) 
     loop0 

它還挺工作。 問題是,我認爲幾乎所有的時間都會觸發一個窗口事件,所以所有的事情都會被觸發,這會讓它變慢。 我怎麼能這樣做,我只有在點擊註冊時才更改圖形?

+1

您能否提一下您使用的窗口庫的軟件包? Gtk2hs? wxHaskell?其他? – 2010-11-05 10:02:29

+1

那麼,在代碼中它看起來像這樣:import Graphics.HGL – 2010-11-05 11:22:47

回答

0

如果我在繪製新東西之前調用clearWindow,它會有所幫助。我不明白爲什麼。它是否會安排重新繪製窗口? 很高興知道,但總的來說現在這個問題已經解決了。

1

首先,getWindowEvent將阻塞,直到下一個事件發生,所以一切都只繪製在事件上。如果您認爲窗口事件觸發得太頻繁,那麼您可以將事件打印到標準輸出以確定哪些事件被觸發並忽略它(例如,跳過除按鈕事件之外的所有事件的繪圖)。

順便說一句:你不要IORef,你可以通過循環傳遞當前的顏色。

testDemo points = 
runGraphics $ 
    do 
     w <- openWindow "Test" (480, 550) 
     let 
      loop0 color = do 
         e <- getWindowEvent w 
         let newColor = case e of 
             Button {pt=pt, isDown=isDown} 
              | isDown && color == Green -> Red 
              | isDown && color == Red -> Green 
             _ -> color 
         when (newColor != color) (drawInWindow w (withColor color (polyline points))) 
         loop0 color 

     let color = Red 
     drawInWindow w (withColor color (polyline points)) 
     loop0 color 

(代碼不與編譯器進行測試,所以......)

0

感謝您的回答。 根據我對應該做什麼的理解,我稍微修改了代碼。

testDemo points = 
runGraphics $ 
    do 
     w <- openWindow "Test" (480, 550) 
     let 
      loop0 color = do 
         e <- getWindowEvent w 
         let newColor = case e of 
             Button {pt=pt, isDown=isDown} 
              | isDown && color == Green -> Red 
              | isDown && color == Red -> Green 
             _ -> color 
         when (newColor /= color) (drawInWindow w (withColor newColor (polyline points))) 
         loop0 newColor 
     let color = Green 
     drawInWindow w (withColor color (polyline points)) 
     loop0 color 

雖然結果有點粗略。有時顏色立即變化,有時需要很長時間。我相信這可能是一些更新問題,因爲當我關閉一個窗口時,我發現一個發佈的顏色變化發生在窗口消失之前。 有什麼建議嗎?

+0

如果我跳過「when(newColor/= color)」部分它會更好。唯一的問題是,只有在移動鼠標後才能看到新顏色。也許有可能觸發手動重繪窗口? – 2010-11-08 18:31:33