2010-11-05 65 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