Re: ProgressIndicator inside DynamicModule

*To*: mathgroup at smc.vnet.net*Subject*: [mg109966] Re: ProgressIndicator inside DynamicModule*From*: John Fultz <jfultz at wolfram.com>*Date*: Wed, 26 May 2010 07:11:29 -0400 (EDT)

On Thu, 20 May 2010 06:40:08 -0400 (EDT), Albert Retey wrote: > Hi, > >> Alas, can not answer your questions properly, but the following >> modification >> of your code >> seems to also work fine: >> >> DynamicModule[{range ==== {0, 100}, sw ==== False}, >> Module[{pr ==== 0}, >> Grid@{{ >> Button["Push me", >> (sw ==== True; >> Do[pr ==== i; Pause[.02];, {i, range[[1]], range[[2]]}]; >> sw ==== False;), Method -> "Queued"], >> Dynamic@ProgressIndicator[pr, range], >> Dynamic@pr, >> Dynamic@Switch[sw, >> True, "Calculating...", >> False, "Finished.", >> _, "Standing by."]}}]] >> >> The issue seems to be with the <pr> variable. My guess is that by >> localizing <pr> with DynamicModule vs plain Module or not localizing at >> all, >> you somehow indicate to Dynamic that <pr> is going to change due to >> Dynamic >> updating, so Dynamic does not track its possible changes by other means >> (like by explicit assignments in a loop that you have). My guess is >> supported by observing that once you localize with DynamicModule, >> >> 1. Dynamic@ProgressIndicator[pr, range], works while >> ProgressIndicator[Dynamic[pr], range] does not >> >> 2. Consider the following modification: >> >> ClearAll[f]; >> DynamicModule[{pr ==== 0, range ==== {0, 100}, sw ==== False}, >> Grid@{{ >> Button["Push me", >> (sw ==== True; >> Do[pr ==== i; Pause[.02];, {i, range[[1]], range[[2]]}]; >> sw ==== False;), Method -> "Queued"], >> Dynamic@ProgressIndicator[pr, range], >> Dynamic[f[pr]], >> Dynamic@Switch[sw, >> True, "Calculating...", >> False, "Finished.", >> _, "Standing by."]}}] >> >> You will observe that now the value of <pr> inside <f> is being properly >> updated inside Dynamic during the run of your code. In particular, by >> using >> f[x_]:====x, you can get back the desired result - you can even localiz= e >> <f> >> as well as put this definition inside the same DynamicModule (although >> this >> is certainly a hack). In both cases, we replaced Dynamic[pr] with >> something >> else, which apparently made Dynamic properly update the output. Of >> course, >> my observations at best somewhat clarify "how", but not "why" - >> hopefully >> others will have more to say here. >> > Well, I think it's up to someone from WRI to comment, in my opinion it > is certainly a bug, and one that I think I have seen in other cases, but > never was able to track down to something this simple. Here I have some > examples which look very inconsistent to me: > > DynamicModule[{range == {0, 100}, sw == False, pr == 0}, > Grid[{{ > Button["Push me", ( > sw == True; > Do[pr == i; Pause[.02];, {i, range[[1]], range[[2]]}]; > sw ==== False; > ), > Method -> "Queued" > ], > Column[{ > ProgressIndicator[Dynamic[pr], range, ImageSize -> 100], > ProgressIndicator[Dynamic[pr, TrackedSymbols :> {pr}], range, > ImageSize -> 100], > Dynamic[ProgressIndicator[pr, range, ImageSize -> 100]], > ProgressIndicator[Dynamic[pr + 0], range, ImageSize -> 100] > }], > Column[{ > Dynamic[pr, TrackedSymbols :> {pr}], > Dynamic[0 + pr], > Dynamic[pr] > }] > }}] > ] > > If you first look at the second column you will find that just > Dynamic[pr] behaves differently than Dynamic[0+pr], not exactly > something one would expect. At least you can help Mathematica to still > do what you want by using the TrackedSymbols options for Dynamic[pr]. > > Considering that, it is not so surprising that > ProgressIndicator[Dynamic[pr]] does not work, but now you can't even > make it work with neither the TrackedSymbols-Option nor the pr+0 trick > -- even more inconsistency. The case Dynamic[ProgressIndicator[pr]] > seems then to be like the Dynamic[0+pr] case and probably works for the > same reasons... > > Are these bugs? Will they be corrected in future versions? > > When dealing with these issues I would also love to see functionality > which would allow to have some insight in or even control the dependency > tree that Mathematica uses to decide whether it has to update a Dynamic > or not. The concept of Dynamic evaluation to create graphical user > interface really is an interesting idea and has charm and advantages. > But when it is not working reliable, I find it to take more effort > (usually searching for tricks and workarounds) to create nontrivial > interfaces than when using the standard concepts (MVC,Observer,...) in > other languages. There I have to create the dependencies myself, but at > least I have full control over them... > > hth, > > albert This is a thread I normally would have commented on promptly, but life and work sometimes stand in the way of such promptness. To be clear, this is absolutely a bug. The code provided by the original poster was correct (not optimal, but definitely correct) in every way. All of the usages in Albert's response should also have worked. Put very simply, there are some cases where a Dynamic reference to a DynamicModule variable does not properly update in real time as it's being changed by a button press. A similar issue would probably arise from ActionMenu choices, which act much like button presses (although I haven't actually tried it). I could give more exhaustive information about why some things oddly seem to work such as Dynamic[0+pr], but that would require a technical explanation of the system to a greater depth than should be necessary for understanding how to use it for even advanced uses. As Albert suggests, the original user could work around these problems by making the following replacements in his code... Dynamic@ProgressIndicator[Dynamic@pr, range] -> Dynamic[ProgressIndicator[pr, range]] Dynamic@pr -> Dynamic[pr + 0] Speaking to Albert's final points...I wonder, Albert, what you're looking for in terms of controlling the dependency tree that the TrackedSymbols option doesn't offer? But I do appreciate your wanting a better tool for understanding when or why Dynamics fire. I am sometimes reduced to iterative testing with various values of TrackedSymbols to understand which symbol in a complex bit of code is triggering unwanted Dynamic refreshes. It doesn't seem crazy to imagine a tool which could do this for you. Sincerely, John Fultz jfultz at wolfram.com User Interface Group Wolfram Research, Inc.