Haskell 使用reflect.GI.Gtk,如何在事件中使用和强制评估动态
使用reflex-gi-gtk-0.2.0.0时 我可以从事件中访问动态文件:Haskell 使用reflect.GI.Gtk,如何在事件中使用和强制评估动态,haskell,reactive-programming,gtk3,reflex,Haskell,Reactive Programming,Gtk3,Reflex,使用reflex-gi-gtk-0.2.0.0时 我可以从事件中访问动态文件: submitButtonE4 <- eventOnSignal submitButton #clicked ( do let processDyn dynCompany = do case dynCompany of Just company -> do
submitButtonE4 <- eventOnSignal submitButton #clicked
(
do
let processDyn dynCompany = do
case dynCompany of
Just company -> do
path <- chartAnnualROA company fileOptions800x600 --generateChart company
Gtk.imageClear chartImage
Gtk.set chartImage [#file := T.pack defaultReportPath]
--return x -- path
case T.null $ T.pack path of
True -> return "" --dynCompany
Nothing -> return "" -- dynCompany
return $ ffor maybeCompanyDyn processDyn
>>= )
现在我可以把它沉下去,引起评估
sink submitClickStatusLabel[#label:==ffor submitButtonE(T.pack.show)]
在使用第一种方法时,我无法找到任何强制评估的方法。我如何在不使用其他小部件的情况下强制进行评估
谢谢我想你的大部分麻烦来自这样一个事实,你想在
事件信号
中做大量的工作。这个地方并不打算对您的业务逻辑进行实际的繁重工作,也没有为您提供适当的上下文来有效地处理反应式价值观,如您当前所经历的Dynamic
s
eventOnSignal*
函数系列的实际使用情况是为无功网络获取基本输入。按钮提供的输入不包含任何实际信息。它仅在单击按钮时提供信息。对于这种情况,您通常不希望直接使用eventOnSignal
,而是希望使用eventOnSignal0
,所以让我们这样做:
submitClickedE <- eventOnSignal0 submitButton #clicked
这里的赋值类型为processDynD::Dynamic t(IO(可能是公司))
。如您所见,IO
尚未执行。幸运的是,reflection
提供了一个在反应值内执行IO
操作的操作,称为performEvent::Event t(Performable ma)->m(Event ta)
。这种类型有两个方面不太符合我们目前的需要。首先,它希望执行的monad是一个可执行的m
,而我们有IO
,但我们马上就会谈到这一点。第二个也是更紧迫的问题是,performEvent
预期的是事件,而不是动态事件。这是有意义的,因为您不能连续执行IO
操作。您必须决定何时执行IO
操作
a单击submitButton
时,您希望执行IO的UI。因此,我们需要一个事件
,该事件在submitClickedE
激发时激发,但它应该激发processDynD
中的当前值。这样做被称为“使用事件对行为
进行采样”
,可以使用操作符(这是基于Kritzefitz的答案的新版本
用于从组合框中选择公司的事件,与以前相同
companySelectionE <- eventOnAttribute companyCboxBoxEntryWidget #text
submitClickedE现在使用EventSignal0而不是EventSignal
submitClickedE <- eventOnSignal0 submitButton #clicked
submitlickede谢谢,这解释了很多想法。我用新代码发布了一个答案。如果你对performEvent
的结果不感兴趣,但只想执行IO
,你也可以使用performEvent\uu
。说它稍微快一点。你也不需要绑定perfo的结果如果您不打算使用其结果,请将rmEvent
更改为名称。总之,我会将您的最后一行更改为performEvent\uu$runGtk generatechart
。好的。编译并运行良好。
let processDynE = current processDynD <@ submitClickedE
processedCompany <- performEvent $ runGtk <$> processDynE
sink submitClickStatusLabel [#label :== T.pack . show <$> processedCompany]
companySelectionE <- eventOnAttribute companyCboxBoxEntryWidget #text
companySelectionB <- hold Nothing $ ffor companySelectionE (`Map.lookup` companyMap)
let
generateChart company = do
case company of
Just companyJ -> do
chartAnnualROA companyJ fileOptions800x600
Gtk.imageClear chartImage
Gtk.set chartImage [#file := T.pack defaultReportPath]
return ()
Nothing -> return ()
submitClickedE <- eventOnSignal0 submitButton #clicked
let generateChartB = generateChart <$> companySelectionB
let generateChartE = generateChartB <@ submitClickedE
processedCompany <- performEvent $ runGtk <$> generateChartE
companySelectionE <- eventOnAttribute companyCbox #text
companySelectionB <- hold Nothing $ ffor companySelectionE (`Map.lookup` companyMap)
let
generateChart company = do
case company of
Just companyJ -> do
chartAnnualROA companyJ fileOptions800x600
Gtk.set chartImage [#file := T.pack defaultReportPath]
return ()
Nothing -> return ()
submitClickedE <- eventOnSignal0 submitButton #clicked
let generateChartB = generateChart <$> companySelectionB
let generateChartE = generateChartB <@ submitClickedE
processedCompany <- performEvent $ runGtk <$> generateChartE