我想在 wxHaskell 应用程序中动态添加和删除小部件。
我的问题是:
窗口可以调整大小,但是当它手动变大时,单击“更多”按钮会显示它快速闪回到最小大小。如果没有
windowReLayout
调用,窗口根本不会改变大小。windowRemoveChild
看起来像我想要的,但它不是从 WXCore 导出的,所以我猜它不打算在这一层使用(编辑:我也没有找到一种方法来使用它而不会导致程序崩溃,因为它试图绘画到一个不存在的窗口中,即使先将其从布局中删除,然后将其从其父窗口中删除)。但我找不到替代方案。这个答案建议简单地隐藏小部件,但在我的真实应用程序中,我使用的是一个复杂的自定义小部件,我希望收集垃圾。创建小部件时已经定义了父/子关系,我可以为布局再次这样做吗?例如,我是否可以为面板提供一个
row 5
自动应用于其所有子级的布局,而不必为每次更改重新构建布局?(如果我只是从布局中删除子级但不从其父级中删除它们,它们将简单地定位在原点,这是由一种默认布局控制的吗?)
这是一个最小的示例,显示了我当前如何添加小部件,以及我如何尝试删除它们。
module Main where
import Graphics.UI.WX
main :: IO ()
main = start $ do
count <- varCreate 100
items <- varCreate []
f <- frame []
cont <- panel f []
-- add a button
more <- button f
[ text := "more"
, on command := do
n <- varGet count
varSet count (n + 1)
new <- button cont
[ text := show n
, on command := print n ]
is <- varGet items
let is' = new : is
varSet items is'
set cont [ layout := row 5 (map widget is') ]
windowReLayout f
]
-- remove a button
less <- button f
[ text := "less"
, on command := do
is <- varGet items
case is of
i : is' -> do
-- windowRemoveChild f i -- crash
set i [ visible := False ] -- leak
set cont [ layout := row 5 (map widget is') ]
varSet items is'
return ()
_ -> return ()
]
set f [ layout := margin 5
$ column 5 [ row 5 [ widget more
, widget less ]
, widget cont ] ]