Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I need to perform a long action with a button. I tried setting the DynamicEvaluationTimeout, but it seems it doesn't work for me. So I want to try using several buttons to compute pieces of the whole task and here's where my problem starts: How to tell Mathematica that a button should be pressed (or have its action performed) without actually pressing the button by user? Is there a way to emulate such a thing from within the code? I need to use the preemptive link, so Method -> "Queued" is not the solution I'm looking for.

share|improve this question
    
Welcome to Mathematica.SE! Could you please post a working minimal example of your case? –  István Zachar Oct 27 '12 at 9:14
    
Welcome to Mathematica.SE! I suggest the following: 1) As you receive help, try to give it too, by answering questions in your area of expertise. 2) Read the FAQs! 3) When you see good Q&A, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge. ALSO, remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign` –  chris Oct 27 '12 at 10:16
    
You may find this thread relevant: How to Initiate a queued evaluation from a Dynamic GUI without using a Button. –  István Zachar Mar 29 '13 at 8:39
    
@Daroslav: can you explain why you (think you) need the preemptive link? If your calculation takes time, using the queued link seems to be your best choice. From what you write I'm not convinced that what you need can't be done with Method->"Queued". I think you should explain better what you try to do and why -- probably without preemptively excluding possible solutions. And remember: providing an example (especially if it demonstrates what does not work) for people to play with will always help a lot to get better answers. –  Albert Retey Apr 3 '13 at 18:11

1 Answer 1

One can come up with some messy method to evaluate a front-end button programmatically, but I think it is easier to separate the button functionality from the button itself, as listenerButtonFunction[]. Here I introduce a timer button that, if pushed, counts down simulating a long calculation. When it finishes, it switches the flag active to True. The second button has a Dynamic wrapper and thus it listens to the changes made to active: whenever active is set to True, the appearance of the listener button is changed. Now the functionality of the listener button is separated, so we can call it right after setting active = True in the first button, simulating the manual push of the listener button.

Note that I only used Method -> "Queued" to see how the timer goes down. If omitted, the listener still will be activated in due time. Also, the listener button can be pushed on its own.

active = False;
n = 0;
listenerButtonFunction[] := Print["Listener activated"];
Row@{Button["Timer", active = False; n = 100; 
   Do[Pause[.02]; n = n - 1, {i, 100}]; active = True; 
   listenerButtonFunction[], Method -> "Queued"], Spacer@5, Dynamic@n}
Dynamic@If[active,
  Button["Listener: ACTIVE", active = False, 
   Appearance -> {Automatic, "Pressed"}],
  Button["Listener: inactive", listenerButtonFunction[], 
   Appearance -> Automatic]
  ]

enter image description here

Update

The following method creates a button that is wrapped in Dynamic that listens to the state change of the switch active, which can be changed by either hitting the second button or waiting for the calculation of the first button to finish (just like above). The function of this second button is actually performed by the Dynamic wrapper whenever active becomes True. The Print statement is redirected by default to the Messages window, but if listenerFunction is e.g. a long calculation that does not print anything, this shouldn't matter.

active = False; n = 0;
listenerFunction[] := Print["Listener pushed"];

Row@{Button["First", active = False; n = 100; 
   Do[Pause[.005]; n = n - 1, {i, 100}]; active = True;, 
   Method -> "Queued"], Spacer@5, Dynamic@n}

Dynamic[If[active, listenerFunction[]]; 
 Button[If[active, "active", "inactive"], active = ! active]]
share|improve this answer
    
That's an interesting approach, but I can't see it working for me. –  Daroslav Oct 27 '12 at 10:35
    
@Daroslav Where does it fail? Perhaps set the Pause value to something smaller? Make sure that you evaluate it with a fresh kernel. –  István Zachar Oct 27 '12 at 10:40
    
I'm sorry, I pressed enter too soon. Here's the rest of my comment: I want to use my button to run an animation with a dynamic Graphics object. Since it's long, the preemptive link times out. The good news is, I can split it into parts. So I need a Button, that will do a part of the job, and then calls itself (or a different Button) to do a part of the rest of the job, and so on. –  Daroslav Oct 27 '12 at 10:42
    
@Daros You could put the "rest of the job" into listenerButtonFunction, and you can link an infinite number of buttons in this way. –  István Zachar Oct 27 '12 at 11:13
    
I just thought I could, guess I needed some time to digest your idea ;) Thanks, that's really helpful, I'll try to adapt that. –  Daroslav Oct 27 '12 at 11:31

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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