I have a dynamic module that contains some basic PopupMenu's and Buttons but also need to use the variables returned from these buttons and PopupMenu's in my nb functions outside of this DynamicModule. Here is the code:

DynamicModule[{var = 1, var2 = 3},
  {PopupMenu[pass2Fun1 = Dynamic[var], {1 -> "Return 1", 2 -> "Return 2", 
   3 -> "Return 3"}, ContinuousAction -> True]},
  Switch[var, 1,
   {Button["One", Module[{data = SystemDialogInput["FileOpen"]}, {}], 
   Method -> "Queued"]}, 2,
    {Button["Two", Module[{data2 = SystemDialogInput["FileOpen"]}, {}], 
     Method -> "Queued"], 
     Button["Three",Module[{data3 = SystemDialogInput["FileOpen"]}, {}], 
     Method -> "Queued"]}, 3,
    {Button["Four", Module[{data4 = SystemDialogInput["FileOpen"]}, {}], 
    Method -> "Queued"],
  PopupMenu[pass2Fun2 = Dynamic[var2], {3 -> "choice 1", 4 -> "choice 2", 
    5 -> "choice 3"}, ContinuousAction -> True]}
 ]]], TrackedSymbols :> {var, var2}]]

pass2Fun1 and pass2Fun2 are variables that are needed outside the Dynamic Module, and of course so are the SystemDialogInput variables.

Take for example the If statement code where we can test to see if the variable pass2Fun1 ==1 To run this test place the above Dynamic Module code in a cell and check to see that the variable pass2Fun1 is filled as Global` Then run the If statement code in another cell to see if you get a good printed result.

 If[pass2Fun1 == 1,
 Print["This works", pass2Fun1],
 Print["Broken", pass2Fun1]]

The If statement can not see the variable pass2Fun1==1 but If I print that variable it prints. If I check the context and the context path both are Global`.

Now for the fun Part: In a separate cell evaluate:


Then run the If statement again. Now the code runs fine. I thought we had a solution but further checking revealed this strange behavior. After trying Rojo's code below you will see that this If statement will still not complete. So in both the example code above and Rojo's solution below the result in the If statement test is the same. Rojo's code in the above function:

DynamicModule[{pass2Fun1 = 1, pass2Fun2 = 3}, 
     Dynamic[pass2Fun1], {1 -> "Return 1", 2 -> "Return 2", 
      3 -> "Return 3"}, ContinuousAction -> True]}, 
    1, {Button["One", 
      Module[{data = SystemDialogInput["FileOpen"]}, {}], 
      Method -> "Queued"]}, 
    2, {Button["Two", 
      Module[{data2 = SystemDialogInput["FileOpen"]}, {}], 
      Method -> "Queued"], 
      Module[{data3 = SystemDialogInput["FileOpen"]}, {}], 
      Method -> "Queued"]}, 
    3, {Button["Four", 
      Module[{data4 = SystemDialogInput["FileOpen"]}, {}], 
      Method -> "Queued"], 
      Dynamic[pass2Fun2], {3 -> "choice 1", 4 -> "choice 2", 
       5 -> "choice 3"}, ContinuousAction -> True]}]]], 
  TrackedSymbols :> {pass2Fun1, pass2Fun2}]]

My question: What is the best method to get the variable data from another nb a Button or PopupMenu to the functions in a different nb? These nb functions control the generation of results based on the input data and the variables pass2Fun1 & 2 and the SystemDialogInputs. Should all the functions be called inside the DynamicModule or made Global? Even if it's made Global as in the case above, how do I make sure the variable is filled in such a way as to be useful to other functions?

Thanks in advance for the help!

  • $\begingroup$ It would help to better understand your question to provide a use case example and the behaviour you'd like. For example, what do you mean by "to get the variable data to the functions in a notebook"? $\endgroup$ – Rojo Jul 20 '12 at 18:41
  • $\begingroup$ Thanks, still have some doubts that I think are relevant. So all you want to do with those variables is have some other interface element display some result of processing them? No need to have them available to write new code and evaluate cells playing with the data? Is the interface element that shows the rsult part of the same cell or from another one? If it's from another one, is it already part of the notebook or generated when you click a button or something (as a dialog would for example?) $\endgroup$ – Rojo Jul 20 '12 at 20:26
  • 1
    $\begingroup$ If what you want is to simply have them available in a variable, to play around, do further calculations, etc, it makes the most sense to me to store them in a kernel variable. It can be global or it can belong to a context $\endgroup$ – Rojo Jul 20 '12 at 21:14
  • $\begingroup$ You still don't provide code to test. I'd honestly suggest you edited your question, and at least append at the end whatever code you think should be run (the one you refer to from my answer) so that anyone with a fresh kernel can be sure what to copy and paste to see what you mean $\endgroup$ – Rojo Jul 23 '12 at 13:23
  • $\begingroup$ The code in my answer not only uses a pass2Fun2 and uses numbers 3,4 and 5 for the choices, so you could never expect it to assign pass2Fun1 the number 1 $\endgroup$ – Rojo Jul 23 '12 at 13:24

You have your PopupMenu wrong

This is the proper way to write it if you want pass2Fun2 to be kept updated with the PopupMenu selection

Dynamic[pass2Fun2], {3 -> "choice 1", 4 -> "choice 2",
5 -> "choice 3"}, ContinuousAction -> True]

This goes for both popups

You had

PopupMenu[pass2Fun2 = Dynamic[var2], ...

After doing those changes you need to remove pass2Fun1 and pass2Fun2 from the local variable list of your DynamicModule if you want to be able to access them from other cells

| improve this answer | |
  • 1
    $\begingroup$ PopupMenu[pass2Fun1 = Dynamic[var1], ... might be considered unconventional but the global value still updates using the OPs code -- in my notebook anyway. So while this is more elegant, and the way you would normally write this sort of code, what does it actually fix (a question for @RHall) $\endgroup$ – Mike Honeychurch Jul 21 '12 at 0:40
  • 1
    $\begingroup$ @MikeHoneychurch, PopupMenu[pass2Fun1 = Dynamic[var1]... doesn't keep the global up to date. But the global, in StandardForm displays as the dynamic value of var1 which is local to a different cell. So as long as the cell doesn't "resynch" with the kernel, it maay work visually, but I think that's playing with fire $\endgroup$ – Rojo Jul 21 '12 at 0:42
  • 1
    $\begingroup$ @MikeHoneychurch the OP, for example, couldn't use the global as a parameter to another function (because it was actually a Dynamic[var] and not a value), so he got confused. Then he tested assigning pass2Fun1=1 manually, but now could never get the PopupMenu to ""update"" pass2Fun1 any more dynamically $\endgroup$ – Rojo Jul 21 '12 at 0:44
  • $\begingroup$ @RHall, the Popup was changing the local "var", but doing nothing to pass2Fun1. But pass2Fun1 was linked visually to the "var" so it appeared to more or less work fine $\endgroup$ – Rojo Jul 21 '12 at 0:46
  • $\begingroup$ @Rojo I see. yes very confusing. $\endgroup$ – Mike Honeychurch Jul 21 '12 at 0:48

This answer maybe redundant, if not it may clarify what is required or not.

This is a minimal function that creates a dialog holding a popup which is linked to a Dynamic kernel variable without the use of Module or DynamicModule.

ff[] := (pup = 
    Dynamic[pass2Fun1], {1 -> "choice 1", 2 -> "choice 2", 
     3 -> "choice 3"}, ContinuousAction -> True]; 


As far as I can tell the two remain in sync if the kernel variable is set or the menu item selected.

Does this meet the criteria for the OP?

| improve this answer | |
  • $\begingroup$ Yes it does, Thanks very much! $\endgroup$ – R Hall Jul 24 '12 at 18:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.