Как использовать макрос из макроса в определении элементов управления Manipulate? - PullRequest
1 голос
/ 10 декабря 2011

Я использую метод макроса Леонида ( см. Здесь ), чтобы помочь мне управлять макетом управляющих переменных Manipulate.

Но я обнаружил, что из макроса я не могу использовать другой макрос, определенный в другом месте.Так что мне интересно, есть ли способ использовать макрос из другого макроса?

Чтобы объяснить вопрос, я сначала покажу очень простую манипуляцию с использованием одноуровневого макроса, затем я покажу проблему,пытаясь использовать макрос из другого.

Manipulate[Text["ok"],

 Evaluate@With[{

    x = Function[{},  (*----> macro x *)
      TabView[{
        "x" -> "working on x"
        }], HoldAll
      ],

    y = Function[{}, (*----> macro y *)
      TabView[{
        "y" -> "working on y"
        }], HoldAll
      ]
    },(*WITH*)

   (* now use the above macros *)
   Grid[{
     {SetterBar[Dynamic[choice], {1, 2}]},
     {Dynamic[Which[choice == 1, x[], choice == 2, y[]] ]}
     }]

   ],
 {{choice, 1}, None},
 ContentSize -> 300

 ]

enter image description here

Теперь добавьте макрос для флажка, а затем попробуйте использовать его из макроса 'x' выше:

Манипулировать [Text ["ok"],

 Evaluate@With[{

    checkBox = Function[{}, Checkbox[Dynamic[c]], HoldAll],

    x = Function[{},
      TabView[{
        "x" -> checkBox[] (*=====> DOES NOT WORK, did not bind *)
        }], HoldAll
      ],

    y = Function[{},
      TabView[{
        "y" -> "working on y"
        }], HoldAll
      ]
    },(*WITH*)

   Grid[{
     {SetterBar[Dynamic[choice], {1, 2}]},
     {Dynamic[Which[choice == 1, x[], choice == 2, y[]] ]}
     }]

   ],
 {{choice, 1}, None},
 {{c, True}, None},
 ContentSize -> 300

 ]

Мы видим, что это не сработало.Макрос «x» не «видел» макрос флажка.

enter image description here

Но если я добавлю код для флажка непосредственно в макрос 'x', он, конечно, будет работать:

Manipulate[Text["ok"],

 Evaluate@With[{

    x = Function[{},
      TabView[{
        "x" -> Checkbox[Dynamic[c]]  (* add the definition directly *)
        }], HoldAll
      ],

    y = Function[{},
      TabView[{
        "y" -> "working on y"
        }], HoldAll
      ]
    },(*WITH*)

   Grid[{
     {SetterBar[Dynamic[choice], {1, 2}]},
     {Dynamic[Which[choice == 1, x[], choice == 2, y[]] ]}
     }]

   ],
 {{choice, 1}, None},
 {{c, True}, None},
 ContentSize -> 300

 ]

enter image description here

Итак, вопрос в следующем: возможно ли использовать макрос, установленный выше, внутри макроса 'x'?

Чтобы сделать это проще, я НЕ передаю никакие аргументы макросам.Я просто использую макрос в качестве короткого имени для фрагмента большего фрагмента кода (определение управляющей переменной), как показано выше.

Это только для того, чтобы мне было проще расположить пользовательский интерфейс, перемещая только имя макроса, вместо перемещения большего фрагмента кода, который определяет макрос.Поскольку для Manipulate нет построителя графического интерфейса, этот метод помогает, когда имеется много элементов управления для управления.

Ответы [ 2 ]

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

Это потому, что вам нужен вложенный With в этом случае. Вы не можете использовать объявление одной переменной в другой в том же списке объявлений в With. Вот упрощенная версия вашей проблемы:

In[3]:= With[{a=b,c=f[a]},g[c]]
Out[3]= g[f[a]]

Это то, что вам нужно вместо:

In[5]:= 
With[{a=b},
  With[{c=f[a]},g[c]]]

Out[5]= g[f[b]]

в вашем случае checkBox играет роль a, а x играет роль c.

Тема о том, как создать версию With, которая позволила бы такие последовательные привязки, обсуждалась несколько раз в Mathgroup и здесь, в SO. Вот моя реализация такой конструкции:

ClearAll[LetL];
SetAttributes[LetL, HoldAll];
LetL /: Verbatim[SetDelayed][lhs_, rhs : HoldPattern[LetL[{__}, _]]] :=
   Block[{With}, Attributes[With] = {HoldAll};
     lhs := Evaluate[rhs]];
LetL[{}, expr_] := expr;
LetL[{head_}, expr_] := With[{head}, expr];
LetL[{head_, tail__}, expr_] := 
  Block[{With}, Attributes[With] = {HoldAll};
     With[{head}, Evaluate[LetL[{tail}, expr]]]];

Если вы хотите его использовать, все, что вам нужно сделать, это изменить With на LetL в вашем коде.

1 голос
/ 12 декабря 2011

Я новичок в этом сайте, поэтому то, что вы пытаетесь сделать, может иметь разные цели, но есть ли причина, по которой вы не можете просто написать это напрямую?

DynamicModule[{choice = 1, c = False},

 Grid[{
   {SetterBar[Dynamic[choice], {1, 2}]},
   {Dynamic[
     Which[choice == 1, TabView[{"x" -> Checkbox[Dynamic[c]]}], 
      choice == 2, TabView[{"y" -> "working on y"}]]]},
   {Dynamic[choice], Dynamic[c]}
   }]
 ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...