4

我想在 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 ] ]
4

0 回答 0