任何在需要的点之间在行之间添加分隔符的技巧

Nas*_*ser 5 wolfram-mathematica

要在网格中的行之间添加分隔符,我知道如何操作的一种方法是使用该Dividers选项.但是最后会使用它,然后必须知道分隔符需要在其下面的行号.因此,对于大型网格,我发现自己使用反复试验,直到找到正确的行号.然后,当我稍后更改网格时,我必须再次进行试验和错误,以便将分隔符放在正确的位置,以防它在我的更改后移动.

在这个例子中,有一个有3行的网格,我想在第二行下面添加分隔符,所以我可以这样做:

Grid[{
  {1},
  {2},
  {3}
  }, Frame -> True, Dividers -> {All, 3 -> True}]
Run Code Online (Sandbox Code Playgroud)

另一种方法,是把FalseTrue以正确的顺序,我希望有一个分频器,这样

Grid[{
  {1},
  {2},
  {3}
  }, Frame -> True, Dividers -> {All, {True, False, True, True}}]
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

如果我可以做这样的事情会很好(就像人们可以为Manipulate做的那样)(当然下面这里不起作用)

Grid[{
  {1},
  {2},
  Delimiter,
  {3}
  }, Frame -> True]
Run Code Online (Sandbox Code Playgroud)

要么

Grid[{
  {1},
  {Item[2,Dividers->True]},
  {3}
  }, Frame -> True]
Run Code Online (Sandbox Code Playgroud)

或者这样的事情.

它将使代码维护更容易.

我看过使用Item等等,但是无法弄明白.

有谁知道这样做的伎俩?

编辑:

顺便说一下,如果可能,这个技巧不仅适用于分频器.但是,能够执行许多其他网格选项(现在在网格级别完成)也可以在项目级别完成.例如,如果我想在某一行之后添加额外的空格,那么按照我想要的速度更容易说出来.此外,如果我想更改项目大小,更容易在现场执行,对于Spacings等也是如此.因此,当移动/复制整行或项目的代码时,它是自包含的并将其全部复制选项在一起.

我想现在这可能需要一个新选项添加​​到Mathematica网格,以使其正常工作并与所有网格设计保持一致.

这是为Mathematica制作GUI构建器之前的全部内容.

我发现当我编写演示程序时,我花费了超过60%的时间来使GUI适合并且看起来正确.使用GUI构建器,我可以花时间处理算法.当我使用Matlab GUIDE制作GUI时,我花费不到5%的时间来制作类似的GUI.

我希望WRI能够为Mathematica制作一个GUI构建器,我想如果你问我,这将成为Mathematica的杀手级应用程序.但没有人问我:)

编辑(2)

评论下面的先生精灵解决方案.
我主要想要这个功能用于我用来布局控件的网格Manipulate.这是一个简单的例子:

Manipulate[x,

 Grid[{
   {Control[{{x, 0, "x"}, 0, 10, 1}]},
   {Control[{{y, 0, "y"}, 0, 10, 1}]}
   }, Frame -> None, Dividers -> {None, {False, True, False}}
  ]
 ]
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

(我必须使用它Grid来设置控件).我不能在这里使用函数调用.我无法使用下面的向导解决方案编写以下内容:

Manipulate[x,

 myGrid[{
   {Control[{{x, 0, "x"}, 0, 10, 1}]},
   spec["Divider"],
   {Control[{{y, 0, "y"}, 0, 10, 1}]}
   }, Frame -> None
  ],

 Initialization :>
  {
   specfunc["Divider", lst_] := Dividers -> {None, # -> True & /@ lst};

   myGrid[dat_, opts : OptionsPattern[]] :=
    Module[{x = 1}, 
     Grid[#, opts, Sequence @@ #2] & @@ 
      Reap[If[MatchQ[#, _spec], Sow[x, #[[1]]]; ## &[], x++; #] & /@ 
        dat, _, specfunc]
     ]

   }
 ]
Run Code Online (Sandbox Code Playgroud)

这给出了一个错误,因为Mathematica在读取和处理初始化部分之前尝试首先读取Manipulate的主体来解析它.

但是在Manipulate之外,它的作用是:

myGrid[{
  {Control[{{x, 0, "x"}, 0, 10, 1}]},
  spec["Divider"],
  {Control[{{y, 0, "y"}, 0, 10, 1}]}
  }, Frame -> None
 ]

specfunc["Divider", lst_] := Dividers -> {None, # -> True & /@ lst};
myGrid[dat_, opts : OptionsPattern[]] :=
 Module[{x = 1}, 
  Grid[#, opts, Sequence @@ #2] & @@ 
   Reap[If[MatchQ[#, _spec], Sow[x, #[[1]]]; ## &[], x++; #] & /@ 
     dat, _, specfunc]
  ]
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我需要花更多的时间在这上面,看看我是否可以让它在Manipulate内部工作.

顺便说一下,让这样的东西在Manipulate里面工作真的很难.我知道的唯一技巧是使用With[{},.... Grid....]我从Leonid学到的模式的宏.

例如这些困难,请参阅我的这个问题

如何在一个地方定义与With []一起使用的常量,然后再应用它们?

编辑(3) 我做错了什么,但是我在Manipulate中遇到了一些错误:

第一个例子:

Manipulate[x,

 Evaluate@grid[{
    {Control[{{x, 0, "x"}, 0, 10, 1}]}
    }
   ],

 Initialization :> 
  {
   grid[tab_, opts___] := 
     Module[{divlocal, divglobal, div, pos}, 
      divglobal = (Dividers /. opts) /. Dividers -> {False, False};
      If[Depth[divglobal] == 1, divglobal = {divglobal, divglobal}];
      If[Length[divglobal] == 1, AppendTo[divglobal, False]];
      pos = Position[tab, Dividers -> _, 1];
      divlocal = 
       MapIndexed[# - #2[[1]] + 1 -> Dividers /. tab[[#]] &, 
        Flatten[pos]];
      divglobal[[2]] = {divglobal[[2]], divlocal};
      Grid[Delete[tab, pos], Dividers -> divglobal, opts]];


   }
 ]
Run Code Online (Sandbox Code Playgroud)

给出错误:

ReplaceAll::rmix: Elements of {False,{}} are a mixture of lists and nonlists. >>
Run Code Online (Sandbox Code Playgroud)

如果我用以上代替上面的话也一样

Evaluate@grid[{
   Dividers -> {Thick, Blue},
   {Control[{{x, 0, "x"}, 0, 10, 1}]}
   }
  ],
Run Code Online (Sandbox Code Playgroud)

试图Dynamic@取代Evaluate@没有运气.可能是小修理是什么需要的?或者我没有使用它?

Hei*_*ike 4

该解决方案应该允许您将表中指定的行之间的分隔符规范与使用该Dividers选项指定的分隔符规范结合起来。

grid[tab_, opts___] :=
 Module[{divlocal, divglobal, div, pos},

  (* extract option value of Dividers from opts to divglobal *)
  (* default value is {False, False} *)
  divglobal = (Dividers /. {opts}) /. Dividers -> {False, False};

  (* transform divglobal so that it is in the form {colspecs, rowspecs} *)
  If[Head[divglobal] =!= List, divglobal = {divglobal, divglobal}];
  If[Length[divglobal] == 1, AppendTo[divglobal, False]];

  (* Extract positions of dividers between rows from tab *)
  pos = Position[tab, Dividers -> _, 1];

  (* Build list of rules for divider specifications between rows *)
  divlocal = MapIndexed[# - #2[[1]] + 1 -> Dividers /. tab[[#]] &, Flatten[pos]];

  (* Final settings for dividers are {colspecs, {rowspecs, divlocal}} *)
  divglobal[[2]] = {divglobal[[2]], divlocal};
  Grid[Delete[tab, pos], Dividers -> divglobal, opts]]
Run Code Online (Sandbox Code Playgroud)

要指定行之间的分隔线,您需要在所需位置插入、Dividers->spec或图形指令(颜色、厚度等)。例如specFalseTrue

tab = {{1, 2, 3}, Dividers -> {Thick, Blue}, {4, 5, 6}, {7, 8, 9}, 
   Dividers -> False, {10, 11, 12}};

grid[tab, Dividers -> All]
Run Code Online (Sandbox Code Playgroud)

数学图形

编辑

应向导先生的要求,我在我的代码中添加了一些注释。