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.

Button[] beguiles me. A simple example follows:

b1 = Button["Evaluate", Cos[Pi/6], Method -> "Queued"]
b2 = Button["Evaluate", Print[Cos[Pi/6]], Method -> "Queued"]

Both of the above statements produce buttons. When one clicks on b1, it appears to evaluate something, but does not output or display anything. Clicking on b2 displays the expected output.

But clicking a second time on b2 prints the expected result a second time. Continuing to click on b2 just increases the list of printed results. This uselessly clutters the notebook I want to distribute.

I want a Button[] to execute a function and simply display its results as near as possible to what pressing Shift + Return in an input cell would do.

I further want it to overwrite previous output.

Ideally I would place the Button[] expression in a hidden initialization cell so only the actual button appears in the deployed notebook.

Does anyway exist to get a Button to do what I've described? How?

share|improve this question
    
Good question. In normal evaluation CellPrint overwrites the previous output but it does not work from within Button, at least as I tried it. –  Mr.Wizard Jan 25 '13 at 23:37
    
@Mr.Wizard -- Any thoughts on why the difference? –  Jagra Jan 26 '13 at 2:49

3 Answers 3

up vote 4 down vote accepted

You could try something like:

y = 0; 
b1 = Button["Evaluate", y = Cos[Pi/6] (++y), Method -> "Queued"]
Dynamic@y

Mathematica graphics

share|improve this answer
    
I must not have made described what I need to do clearly. When I click the Button a 2nd or 3rd time I need it to completely overwrite the output, neither adding to a list of printed results nor nesting the evaluation as you show above. In use I'll have some input variables that may get changed between the times someone clicks the button. I want a Button that will simply evaluate an expression and give me the same output I'd get from evaluating an input cell. Still, I wonder if you've pointed me in a productive direction. I'll try some things. Thx. –  Jagra Jan 25 '13 at 19:01
1  
@Jagra My evaluation is recursive just because I wanted it.You may evaluate whatever you want –  belisarius Jan 25 '13 at 19:04
    
Got it working. Many thanks. –  Jagra Jan 25 '13 at 19:32

Sometimes Dynamic is not really needed. In Version 9 you can use the nice new Cells[] construct. So the button could look like

CellPrint@ExpressionCell[Button["Evaluate",
   NotebookDelete[Cells[CellTags -> "calculationbutton"]];
   CellPrint@ExpressionCell[Cos[Pi/6],
     "Output", CellTags -> "calculationbutton"], Method -> "Queued"], 
  "Text"]

And I would also just close the instruction cell to hide it, e.g.:

Cell[CellGroupData[{Cell[BoxData[
 RowBox[{"CellPrint", "@", 
  RowBox[{"ExpressionCell", "[", 
   RowBox[{
    RowBox[{"Button", "[", 
     RowBox[{"\"\<Evaluate\>\"", ",", "\[IndentingNewLine]", 
      RowBox[{
       RowBox[{"NotebookDelete", "[", 
        RowBox[{"Cells", "[", 
         RowBox[{"CellTags", "->", "\"\<calculationbutton\>\""}], 
         "]"}], "]"}], ";", "\[IndentingNewLine]", 
       RowBox[{"CellPrint", "@", 
        RowBox[{"ExpressionCell", "[", 
         RowBox[{
          RowBox[{"Cos", "[", 
           RowBox[{"Pi", "/", "6"}], "]"}], ",", 
          "\[IndentingNewLine]", "\"\<Output\>\"", ",", 
          RowBox[{
          "CellTags", "\[Rule]", "\"\<calculationbutton\>\""}]}], 
         "]"}]}]}], ",", 
      RowBox[{"Method", "\[Rule]", "\"\<Queued\>\""}]}], "]"}], ",", 
    "\"\<Text\>\""}], "]"}]}]], "Input",
 CellGroupingRules->{GroupTogetherGrouping, 10000.}],

Cell[BoxData[
 ButtonBox["\<\"Evaluate\"\>",
  Appearance->Automatic,
  ButtonFunction:>(NotebookDelete[
     Cells[CellTags -> "calculationbutton"]]; CellPrint[
     ExpressionCell[
      Cos[Pi/6], "Output", CellTags -> "calculationbutton"]]),
  Evaluator->Automatic,
  Method->"Queued"]], "Text",
 CellGroupingRules->{GroupTogetherGrouping, 10000.},
 GeneratedCell->True,
 CellAutoOverwrite->True]
}, {2}]]
share|improve this answer

Another approach is to make the button disable itself.

DynamicModule[{enabled = True}, 
  Dynamic@Button["Evaluate", enabled = False; Print[Cos[Pi/6]], 
  Method -> "Queued", Enabled -> enabled]]

Before clicking on the button

before-clicking

After clicking

after-clicking

share|improve this answer

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.