我想创建一个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
它有点有效。 问题是,我认为几乎所有时间都会触发一个窗口事件,因此所有时间都会被绘制,这使得它变慢。 我怎么能这样做,我只在注册点击时更改图纸?
答案 0 :(得分:1)
首先,getWindowEvent
将阻塞,直到下一个事件发生,因此所有内容仅在事件上绘制。如果您认为窗口事件经常被触发,那么您可以将事件打印到标准输出以找出触发的事件并忽略它(例如,跳过除了按钮事件之外的所有事件的绘图)。
BTW:你没有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
(代码未经编译器测试,因此......)
答案 1 :(得分: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
但结果有点粗略。有时颜色会立即改变,有时需要很长时间。我相信这可能是一些更新问题,因为当我关闭一个窗口时,我看到在窗口消失之前发生了一个发生的颜色变化。 有什么想法吗?
答案 2 :(得分:0)
如果我在绘制新内容之前调用clearWindow会有所帮助。我真的不明白为什么。是否安排重新绘制窗口? 很高兴知道,但总的来说问题现在已经解决了。