我无法从标签和操作列表中生成按钮。我很确定这与 IO 未得到评估有关('on button buttonActivated action'),但我不确定如何修复它。
我有一个(标签,命令)元组列表,我用它来生成一个按钮,它是关联的 IO () 操作。
调用的函数:'on button buttonActivated action'被调用,但按钮仍然没有注册点击。
module GtkTest where
import qualified Data.Map as M
import Graphics.UI.Gtk
import Graphics.UI.Gtk.Buttons.Button
import Graphics.UI.Gtk.Windows.Window
import Graphics.UI.Gtk.Layout.VBox
import Control.DeepSeq
type Command = String
type ButtonLabel = String
type ButtonAction = IO ()
type ButtonDesc = (ButtonLabel, Command)
data ButtonInfo = ButtonInfo {
buttonLabel :: ButtonLabel
, buttonAction :: ButtonAction
, buttonIo :: IO Button
}
genAction :: Command -> ButtonAction
genAction command = putStrLn ("Running: " ++ command)
genButton :: ButtonDesc -> ButtonInfo
genButton info = let (label, command) = info
in ButtonInfo label (genAction command) (buttonNewWithLabel label)
getButtonDescs :: IO [ButtonDesc]
getButtonDescs = return [("Ok", "ok"),
("Foo", "foo"),
("Bar", "bar")]
applyAction (ButtonInfo _ action io) = do
--This gets called
putStrLn "applying click handler"
button <- io
--But apparently not this
on button buttonActivated action
addIoToContainer container io = do
widget <- io
containerAdd container widget
main = do
initGUI
window <- windowNew
--These buttons do not work
buttonDescs <- getButtonDescs
buttons <- return $ map genButton buttonDescs
vbox <- vBoxNew True 0
_ <- sequence $ map ((addIoToContainer vbox) . buttonIo) buttons
_ <- sequence $ map applyAction buttons
_ <- containerAdd window vbox
-- This button works
button <- buttonNewWithLabel "Manually made"
on button buttonActivated $ genAction "Manual action"
containerAdd vbox button
onDestroy window mainQuit
widgetShowAll window
mainGUI
任何帮助将非常感激。谢谢你。
编辑:
根据 chi 的回答,我将 ButtonInfo 数据类型更新为不执行 IO,并最终得到一个 IO [ButtonInfo],它允许我绑定操作。
修订来源(工作):
module GtkTest where
import qualified Data.Map as M
import Graphics.UI.Gtk
import Graphics.UI.Gtk.Buttons.Button
import Graphics.UI.Gtk.Windows.Window
import Graphics.UI.Gtk.Layout.VBox
import Control.DeepSeq
type Command = String
type ButtonLabel = String
type ButtonAction = IO ()
type ButtonDesc = (ButtonLabel, Command)
data ButtonInfo = ButtonInfo {
buttonLabel :: ButtonLabel
, buttonAction :: ButtonAction
, buttonWidget :: Button
}
genAction :: Command -> ButtonAction
genAction command = putStrLn ("Running: " ++ command)
genButton :: ButtonDesc -> IO ButtonInfo
genButton info = let (label, command) = info
in do
button <- (buttonNewWithLabel label)
return $ ButtonInfo label (genAction command) button
getButtonDescs :: IO [ButtonDesc]
getButtonDescs = return [("Ok", "ok"),
("Foo", "foo"),
("Bar", "bar")]
applyAction (ButtonInfo _ action widget) = do
putStrLn "applying click handler"
on widget buttonActivated action
addIoToContainer container io = do
widget <- io
containerAdd container widget
main = do
initGUI
window <- windowNew
buttonDescs <- getButtonDescs
buttons <- sequence $ map genButton buttonDescs
vbox <- vBoxNew True 0
_ <- sequence $ map ((containerAdd vbox) . buttonWidget) buttons
_ <- sequence $ map applyAction buttons
_ <- containerAdd window vbox
button <- buttonNewWithLabel "Manually made"
on button buttonActivated $ genAction "Manual action"
containerAdd vbox button
onDestroy window mainQuit
widgetShowAll window
mainGUI