PGF/TikZ 手册第 12.4 节指出使用图形选项,第 120 页(v2.10),可以使用以下方式设置 TikZ 样式:
\tikzset{my style/.style={<tikz options>},...}
但是,在同一手册的几个地方,未记录的宏\tikzstyle
用于设置样式:
\tikzstyle{my style}=[<tikz options>]
我也在几个在线代码示例中看到过这种用法。
为什么有两种设置 TikZ 样式的方法,以及新代码应该使用哪一种?
注意:我实际上知道答案,但我认为这样的有好答案的问题会对其他用户有益。
答案1
pgf-users 列表中的某人写信给 T Tantau:
我建议保留旧语法,
\tikzstyle{my style}=[some options,...]
因为它更易于阅读和理解。新语法适合更“高级”的用户和库编写者。
Till Tantau 的答案:
我对此有点拿不定主意。
首先,出于兼容性的原因
\tikzstyle
将无限期地存在,所以真正的问题是新的代码会更好。我之所以试图消除这个原因
\tikzstyle
是我想鼓励人们尽可能地保持样式设置本地化。因此,通常情况下,样式定义应该在图片开头给出,就像这样\begin{tikzpicture} [some options, first style/.style={blah}, second style/.style={blub}] ... \end{tikzpicture}
然后,如果
tikzpicture
被移动/复制/无论什么,样式都会随之移动。此外,作为选项给出的样式始终适用于整个范围并自动结束于它。不过,我也不太确定这个论点是否有说服力。全局样式仍然必须使用以下方法进行全局设置
\tikzset anyway...
我已经开始将整个文档代码更改到新系统,但似乎并没有改变可读性。
现在,我认为如果您\tikzstyle
在手册的几个地方发现一些问题,那是因为在这些情况下它不是很重要,也许作者忘记更正这个非常大的文档了。
评论:
完整答案可以在网上找到http://osdir.com/ml/tex.pgf.user/2007-08/msg00004.html
答案继续:
无论如何,你现在可以这样说
\tikzstyle{my style}=[draw=#1,fill=#1!20]
我实际上已经扩展了语法,
\tikzstyle
以便也可以提供默认参数,如下所示\tikzstyle{my style}[red]=[draw=#1,fill=#1!20]
我从来没有尝试过这个,因为我不使用
\tikzstyle
。对于 pgfplots,请参阅pgfplots 手册[修订版本 1.8]:
从
pgfplots
1.1 开始,\tikzstyle
应该不再使用设置pgfplots
选项。尽管
\tikzstyle
某些较旧的版本仍受支持,但您应使用或相关变体pgfplotsoptions
替换任何出现的 。\tikzstyle
\pgfplotsset{style name/.style={key-value-list}}
/.append style
然后,在第280页:
请注意,无法使用 TikZ 命令
\tikzstyle{stylename}=[]
。这在以前的版本中是可能的,并且仍然支持向后兼容。但在某些情况下,它可能无法按预期工作。
答案2
TikZ 及其底层引擎 PGF 具有强大的内置模块pgfkeys
。它也可以作为独立包(通过 )使用,\usepackage{pgfkeys}
以操作其他用途的选项。
因此,无论使用哪个命令,每个定义的选项都会以以下形式转到某个指令
\pgfkeys{/key family/key/.subkey = {value list} }
由于 TikZ 是 PGF 引擎的前端,类似于 LaTeX 和 TeX,因此有一个默认的密钥系列tikz
。例如,每次tikzpicture
启动时都会选择tikz
密钥系列,如果没有另行说明,则内部会相应地处理选项。
由于我们主要使用 TikZ 命令,每次定义节点选项等时选择键系列非常繁琐,
tikz
因此这里可以使用快捷方式,这也是本问题的主题。\tikzset
命令定义为
% |\tikzset| is a shortcut to set keys that belongs to the tikz
% family.
\def\tikzset{\pgfqkeys{/tikz}}
因此,\tikzset
是接下来给出的任何东西都属于 TikZ 家族。
到这里,关键的家族部分已经处理好了,我们可以集中精力处理其中的key/.subkey
一部分。如果不参考有关这个问题的手册,就没什么可做的了,而且这一pgfkeys
部分相当全面。我只想强调一下,最常见的两个例子是mykey/.code
和mykey/.style
。
子项/.style
是需要处理的选项的集合或目录,例如“将形状定义为圆形并绘制它,然后运行一些代码,并放置标签并用黄色填充等。”。样式还可以接收一些参数,例如,最后一个例子可以通过输入
\begin{tikzpicture}
\tikzset{mystyle/.style={draw,circle,label={[fill=yellow]0:#1}}}
\node[mystyle=label text] (nodename) {node text};
\end{tikzpicture}
有关更多魔法,例如更多参数等,请参阅手册。为了方便起见,这里是另一个重要的子键/.append style
\begin{tikzpicture}
\tikzset{mystyle/.style={draw,circle,label={[fill=yellow]0:#1}}}
\tikzset{mystyle/.append style={fill=red,rectangle}}
\node[mystyle=label text] (nodename) {node text};
\end{tikzpicture}
它只是将参数添加到键中。请注意,rectangle
位于后方circle
并支配前一个选项,因此节点变为红色矩形。样式规范的顺序很重要。
现在,回到问题!我们有两种方式来指定样式。即:
\tikzset{mystyle/.style= {draw,circle, etc.} }
\tikzset{mystyle/.append style= {rectangle,fill=red, etc.} }
% or ...
\tikzstyle{mystyle}=[draw,circle,label={[fill=yellow]0:#1}]
\tikzstyle{mystyle}+=[fill=red,rectangle]
这两种方式都会得到相同的输出,但是我们看到这种\tikzstyle
形式输入起来更短。除此之外,据我所知没有什么特别的区别。例如,附加操作只需在+
旁边放一个符号即可=
,并且如下所示定义默认值也非常方便。但是tikzstyle
仅限于这种特殊情况,不适用于其他子项,例如,如果您想放置一段代码进行某些计算,您可以直接使用
\tikzset{mystyle/.code={execute whatever is given here}}
但没有\tikzcode
类似的东西来\tikzstyle
实现这一点。
因此,正如 Altermundus 所说,这更像是一条捷径。
感兴趣的朋友可以参阅以下这些命令的定义代码。相关代码在tikz.code.tex
文件第 1143 行给出。
% Styles
\tikzoption{set style}{\tikzstyle#1}
% Handled in a special way.
\def\tikzstyle{\pgfutil@ifnextchar\bgroup\tikz@style@parseA\tikz@style@parseB}
\def\tikz@style@parseB#1={\tikz@style@parseA{#1}=}
\def\tikz@style@parseA#1#2=#3[#4]{% check for an optional argument
\pgfutil@in@[{#2}%]
\ifpgfutil@in@%
\tikz@style@parseC{#1}#2={#4}%
\else%
\tikz@style@parseD{#1}#2={#4}%
\fi%
}%
\def\tikz@style@parseC#1[#2]#3=#4{%
\pgfkeys{/tikz/#1/.default={#2}}%
\pgfutil@in@+{#3}%
\ifpgfutil@in@%
\pgfkeys{/tikz/#1/.append style={#4}}%
\else%
\pgfkeys{/tikz/#1/.style={#4}}%
\fi}
\def\tikz@style@parseD#1#2=#3{%
\pgfutil@in@+{#2}%
\ifpgfutil@in@%
\pgfkeys{/tikz/#1/.append style={#3}}%
\else%
\pgfkeys{/tikz/#1/.style={#3}}%
\fi}
在同一文件的开头,有一条注释直接告诉我们以下故事
\tikzoption
:
% Note: |\tikzoption| is supported for compatibility only. |\tikzset|
% should be used instead.