Как запустить код инициализации для палитры? - PullRequest
8 голосов
/ 28 октября 2011

Иногда было бы предпочтительно иметь некоторый код инициализации для палитр (кнопок).Например, он может определять некоторые функции, используемые кнопками палитры.

Какой самый простой и предпочтительный способ определения / запуска кода инициализации для палитры?

  • Инициализация может выполняться либо при загрузке палитры, либо при первом нажатии любой кнопки ( возможная проблема: что если ядро ​​перезапустится после загрузки палитры?)
  • Определения должны быть как-то локализованы (то есть в их собственном контексте - помогают ли здесь уникальные контексты ноутбука?)
  • Если возможно, я бы предпочел решение с минимальными усилиями (то есть дополнительный код в наименьшем количестве возможных меставтономный файл палитры без дополнительных файлов пакета, создание палитры с использованием существующих удобных инструментов меню палитр или CreatePalette и т. д.)
  • (Можно предположить, что код инициализации выполняется быстро, например, он состоит изтолько определения)

Ответы [ 2 ]

10 голосов
/ 02 декабря 2011

Вы правы, что обеспокоены видимостью проблемы Dynamic. Способ абсолютной гарантии того, что выражение Dynamic будет оценено независимо от видимости какой-либо отдельной ячейки, заключается в использовании NotebookDynamicExpression. Вот пример, который иллюстрирует NotebookDynamicExpression, работающий, когда Dynamic не работает, потому что он скрыт в закрытой группе ячеек:

cell1 = First @ MakeBoxes[
    TextCell["Click to open", "Title", 
        CellMargins -> 0, System`WholeCellGroupOpener -> True],
    StandardForm];
cell2 = First @ MakeBoxes[
    ExpressionCell[DynamicWrapper["hidden cell", Print["DynamicWrapper"]]], 
    StandardForm];
CreatePalette[
    Notebook[{Cell[CellGroupData[{cell1, cell2}, Closed]]}, 
        NotebookDynamicExpression :>
            Dynamic[Refresh[Print["NotebookDynamicExpression"], None]]]]

Когда вы оцениваете это, обратите внимание, что Dynamic в NotebookDynamicExpression оценивается немедленно. DynamicWrapper никогда не оценивает, пока вы не откроете группу ячеек, что вы можете сделать, нажав на текст «Нажмите, чтобы открыть».

В этом примере, кстати, обратите внимание, что я обернул NotebookDynamicExpression с Refresh. Функция Refresh[#, None]& гарантирует, что код оценивается только один раз - при первом открытии записной книжки. В противном случае код будет подчиняться стандартным свойствам Dynamic и оценивать всякий раз, когда изменяется любая из зависимостей.

NotebookDynamicExpression существует с v6, но был задокументирован только в v8. Также задокументированы родственные родственники, CellDynamicExpression и FrontEndDynamicExpression.

4 голосов
/ 28 октября 2011

A DynamicBox с Initialization может выполнять основные функции. Вы можете изменить размер палитры так, чтобы объект не был виден, и он все равно будет работать.

Вот код для небольшой выборочной палитры. Устанавливает значение для var. Активный код смещен пробелом.

(* Beginning of Notebook Content *)
Notebook[{
Cell[BoxData[{
 TagBox[GridBox[{
    {
     ButtonBox["\<\"TSV\"\>",
      Appearance->Automatic,
      ButtonFunction:>None,
      Evaluator->Automatic,
      Method->"Preemptive"]},
    {
     ButtonBox["\<\"CSV\"\>",
      Appearance->Automatic,
      ButtonFunction:>None,
      Evaluator->Automatic,
      Method->"Preemptive"]},
    {
     ButtonBox["\<\"Table\"\>",
      Appearance->Automatic,
      ButtonFunction:>None,
      Evaluator->Automatic,
      Method->"Preemptive"]}
   },
   GridBoxAlignment->{"Columns" -> {{Left}}},
   GridBoxItemSize->{"Columns" -> {{Automatic}}, "Rows" -> {{Automatic}}}],
  "Column"], "\[IndentingNewLine]", 

DynamicBox[Null,
   Initialization :> ($CellContext`var = "It is done, Master.")
]

}], NotebookDefault,
 CellMargins->{{0, 0}, {0, 0}},
 CellBracketOptions->{"Color"->RGBColor[0.269993, 0.308507, 0.6]},
 CellHorizontalScrolling->True,
 PageBreakAbove->True,
 PageBreakWithin->False,
 ShowAutoStyles->True,
 LineSpacing->{1.25, 0},
 AutoItalicWords->{},
 ScriptMinSize->9,
 ShowStringCharacters->False,
 FontFamily:>CurrentValue["PanelFontFamily"],
 FontSize:>CurrentValue["PanelFontSize"]]
},
WindowSize->{55, 105},
WindowMargins->{{Automatic, 583}, {Automatic, 292}},
WindowFrame->"Palette",
WindowElements->{},
WindowFrameElements->{"CloseBox", "MinimizeBox"},
StyleDefinitions->"Palette.nb"
]
(* End of Notebook Content *)
...