SVG widgets Part 4

Difference between version 1 and 3 - Previous - Next
'''See also [SVG widgets Part 1] , [SVG widgets Part 2] & [SVG widgets Part 3]'''

<<inlinehtml>>


<h1 style="text-align:center"><span style="font-size:14pt"><span style="font-family:&quot;Times New Roman&quot;"><span style="font-size:24.0pt">Tcl/tk: SVG widgets. File Explorer and information Widgets. Part 4</span></span></span><img alt="" src="![](https://habrastorage.org/webt/c6/07/cc/c607ccaeec9ace3c7ea33babffe4fb56.png)" /></h1>

<p>&nbsp;</p>

<p><br />
<button class="b1" style="border-radius: 5px; background-color: cyan; font-size: 18px; margin: 0 0 0 100px;"><a href="https://cloudtk-app.tcl-lang.org/cloudtk/VNC?session=new&amp;Tk=SVG-widgets-Part-I" target="_blank">SVG-demo and TkConsole </a> </button>

<p>&nbsp;</p>

<div class="row">
<div class="col-xs-12">
<p><strong>By clicking on the button, an interactive demo is displayed in a new browser tab using <a class="mkup_a mkup_known" href="https://wiki.tcl-lang.org/page/CloudTk">CloudTk</a></strong>.</p>

<p><strong>This article is written by Vladimir Orlov.</strong></p>

<p><span style="font-size:12pt"><span style="font-family:&quot;Times New Roman&quot;">The &quot;<strong><em>SVG widgets for Tcl/Tk</em></strong>&quot; project addresses one of the primary criticisms leveled at the graphical interfaces of applications built using standard <em><strong>Tk</strong></em> widgets: their outdated design. Transitioning from classic <em><strong>Tk</strong></em> widgets to <em><strong>SVG</strong></em> widgets requires minimal effort; I confirmed this firsthand by rewriting the <em><strong>GUI</strong></em> for the <em><strong>cryptoarmpkcs</strong></em> digital signature utility. Distributions of this utility (named <em><strong>cryptoarmpkcs_svg</strong></em>) for <em><strong>Linux64</strong></em> and <em><strong>Win64</strong></em> platforms are <a href="https://github.com/a513/CryptoArmPKCS">available in the project repository</a>:</span></span></p>

<p><img alt="" src="https://habrastorage.org/webt/68/9c/38/689c38790ad881a645f9486cd7c6b05d.gif" /></p>

<p style="margin-left:0cm; margin-right:0cm"><span style="font-size:12pt"><span style="font-family:&quot;Times New Roman&quot;">This screenshot showcases the key features of the <strong><em>SVG</em></strong> widgets project, including the variety of widgets, the design of buttons and frames, and widget fill styles. You can run this example in the demo (using the &quot;<em><strong>SVG-demo and TkConsole</strong></em>&quot; button at the beginning of the article) by clicking the &quot;<em><strong>Examples</strong></em>&quot; button and selecting &quot;<em><strong>SVGpkcs7</strong></em>&quot; from the menu. It also features a scrolling text display reading &laquo;<em><strong>PKCS7 Utility (Public-Key Cryptography Standarts#7</strong></em>)&raquo;. There is animation as well - rotating tokens; if they aren't spinning, simply click on the cyan-colored border. </span></span></p>

<p style="margin-left:0cm; margin-right:0cm"><span style="font-size:12pt"><span style="font-family:&quot;Times New Roman&quot;">However, not everything was perfect. When developing a GUI, one often needs to use a file browser to select files or folders (via <strong><em>tk_getSaveFile</em></strong>, <strong><em>tk_getOpenFile</em></strong>, or <strong><em>tk_chooseDirectory</em></strong>). While <strong><em>Windows</em></strong> and <strong><em>OS X</em></strong> launch their respective native file browsers, <strong><em>Linux</em></strong> platforms load the <strong><em>Tcl/Tk</em></strong> browser. What is the issue with this browser? It lacks basic file and folder operations, such as creating, deleting, or renaming items.</span></span></p>

<p style="margin-left:0cm; margin-right:0cm"><span style="font-size:12pt"><span style="font-family:&quot;Times New Roman&quot;">Consequently, a file browser based on SVG widgets was developed, resulting in the `tkfe_svg` package, which was subsequently added to the `svgwidgets` project:</span></span></p>

<p style="margin-left:0cm; margin-right:0cm"><img alt="" src="https://habrastorage.org/webt/d6/68/42/d668429f4a79f7044a9e6e7029d05bbe.png" style="height:419px; width:850px" /></p>

<div class="row">
<div class="col-xs-12">&nbsp;</div>
</div>

<div>
<div style="background-color:#f7f7f7; border-radius:5px; border:1px solid #0077cc; padding:5px"># Loading the tkfe_svg package<br />
package require tkfe_svg<br />
# Replacing the native file explorer with tkfe_svg<br />
FE::fe_rename</div>
</div>

<div>&nbsp;</div>

<div>Now, when invoking a file dialog (<strong><em>tk_getSaveFile</em></strong>, <em><strong>tk_getOpenFile</strong></em>, or <strong><em>tk_chooseDirectory</em></strong>), the dialog<strong><em> GUI</em></strong> from the <em><strong>tkfe_svg</strong></em> package will be loaded.</div>

<div>To undo the action of the <em><strong>FE::fe_rename</strong></em> operator, simply execute the <em><strong>FE::fe_restore</strong></em> command.<br />
The <em><strong>tkfe_svg</strong></em> package contains three operators: <em><strong>::FE::tk_getopenfile</strong></em>, <em><strong>::FE::tk_getsavefile</strong></em>, and <em><strong>::FE::tk_choosedirectory.</strong></em> If the <em><strong>::FE::fe_rename</strong></em> operator is not used, these commands are called directly.</div>

<p>In addition to options similar to those of the native <em><strong>Tcl/T</strong></em>k file dialog, the tkfe_svg file dialog offers extra options. These allow you to specify, for example, the dialog's width (<em><strong>-width</strong></em>) and height (<em><strong>-height</strong></em>), or to arrange folders and files in separate windows (using the &quot;<em><strong>-sepfolders 1</strong></em>&quot; option) for the <em><strong>::FE::tk_getopenfile</strong></em> and <em><strong>::FE::tk_getsavefile</strong></em> operators.</p>

<div class="row">&nbsp;</div>

<div style="background-color:#f7f7f7; border-radius:5px; border:1px solid #0077cc; padding:5px"># Loading the tkfe_svg package<br />
package require tkfe_svg<br />
# Replacing the native file explorer with tkfe_svg<br />
FE::fe_rename /&gt; #Launch the file explorer to select a file.<br />
tk_getOpenFile -width 10c -height 7c -sepfolders 1<br />
#or<br />
#Restoring the native file explorer<br />
#::FE::fe_restore<br />
::FE::tk_getopenfile -width 10c -height 7c -sepfolders 1</div>

<p><img alt="" src="https://habrastorage.org/webt/ee/f9/58/eef958fe1db15854bcfab831e96eb74a.png" style="height:443px; width:850px" /></p>

<p>You can also configure the file explorer using the &quot;<em><strong>Go configure</strong></em>&quot; button; clicking it opens an intuitive configuration menu:</p>

<p><img alt="" src="https://habrastorage.org/webt/7d/b6/43/7db6431b0a4d1c10b301fda4f4f3f412.png" style="height:407px; width:850px" /></p>

<p>File manager settings are saved upon exit. To restore the default settings, you can execute the<em><strong> ::FE::fe_restore</strong></em> command.</p>

<p>While discussing <em><strong>SVG</strong></em> widgets, we somehow overlooked information widgets&mdash;even though they appeared on your screen if you viewed the demo examples:</p>

<p><img alt="" src="https://habrastorage.org/webt/82/22/54/8222542d96ab57b26a546a8296e3ffd9.png" style="width:850px" /></p>

<p>Information widgets are SVG widgets of the `mbutton` class, created <a href="https://wiki.tcl-lang.org/page/SVG+widgets+Part+2">using one of the following commands</a>:</p>

<p><em><strong>mbutton new &lt;window-ID&gt; [-type &lt;type&gt;] [args]</strong></em></p>

<p>or</p>

<p><em><strong>mbutton create &lt;object-ID&gt; &lt;window-ID&gt; [-type &lt;type&gt;] [args],</strong></em></p>

<p>where <strong><em>&lt;type&gt;</em></strong> takes one of the following values:<em><strong> yesno</strong></em> | <em><strong>msg</strong></em> | <strong><em>left</em></strong> | <em><strong>right</strong></em> | <em><strong>up</strong></em> | <em><strong>down</strong></em> | <em><strong>none</strong></em>.</p>

<p>Thus, there are seven types of information widgets: <em><strong>yesno</strong></em>, <em><strong>msg</strong></em>, <em><strong>left</strong></em>, <em><strong>right</strong></em>, <em><strong>up</strong></em>, <em><strong>down</strong></em>, and <em><strong>none</strong></em>. By default, a widget of type <em><strong>yesno</strong></em> is created.</p>

<p>The following example demonstrates how yesno and msg type SVG widgets are created and how they work:</p>

<div class="row">&nbsp;</div>

<div>
<div style="background-color:#f7f7f7; border-radius:5px; border:1px solid #0077cc; padding:5px">
<p>package require svgwidgets<br />
set textanchor [list nw n ne]<br />
set mtype [list yesno msg yesno]<br />
set txt &quot;\nAre you sure\n&quot;<br />
append txt &quot;sure your choice is correct\n&quot;<br />
append txt &quot;?\n&quot;<br />
lassign {1 0 0} i wm hm<br />
set lmsg [list ]<br />
lassign {8 1.0 100 3 2} fsize fopaci x0 grad wstr<br />
foreach type $mtype {<br />
&nbsp; &nbsp; set tektxt &quot;[set txt](window: .mb$i)&quot;<br />
&nbsp; &nbsp; set msg [mbutton new .mb$i -place window -type $type -fontsize [expr {$fsize * $i}] -text $tektxt -strokewidth [expr {$wstr * $i}]]<br />
&nbsp; &nbsp;set i1 $i<br />
&nbsp; &nbsp;if {$i1 != 1} {<br />
&nbsp; &nbsp; &nbsp; &nbsp;set i [expr {$i - 0.9}]<br />
&nbsp; &nbsp;}<br />
&nbsp; &nbsp;$msg config -fillopacity [expr {$fopaci / $i}] -fillnormal gradient[set grad]<br />
&nbsp; &nbsp;lappend lmsg $msg<br />
&nbsp; &nbsp;set i $i1<br />
&nbsp; &nbsp;incr i<br />
&nbsp; &nbsp;incr grad<br />
}<br />
set i 1<br />
set mend [list]<br />
foreach m $lmsg {<br />
&nbsp; &nbsp;after 0 lappend mend \&quot;.mb[set i] \[$m place -x $x0 -y 100] \&quot;<br />
#Strange comment &quot;<br />
&nbsp; &nbsp;update idletasks<br />
&nbsp; &nbsp;after 100<br />
&nbsp; &nbsp;lassign &quot;[winfo width .mb[set i]] [winfo rootx .mb[set i]]&quot; mw mr<br />
&nbsp; &nbsp;set x0 [expr {$x0 + $mw + $mr + 40}]<br />
&nbsp; &nbsp;incr i<br />
}<br />
foreach w &quot;.mb1 .mb2 .mb3&quot; {<br />
&nbsp; &nbsp;if {[winfo exist $w]} {<br />
&nbsp; &nbsp; &nbsp; tkwait window $w<br />
&nbsp; &nbsp;}<br />
}<br />
puts &quot;Result: [lsort $mend] &quot;</p>
</div>
</div>

<p style="margin-left:0cm; margin-right:0cm"><span style="font-size:12pt"><span style="font-family:&quot;Times New Roman&quot;">If you run this example in the demonstration window, you will get the following image as output:</span></span></p>

<p style="margin-left:0cm; margin-right:0cm"><img alt="" src="https://habrastorage.org/webt/3a/41/34/3a4134a1c7655281541c24659890cffe.png" style="height:365px; width:850px" /></p>

<p style="margin-left:0cm; margin-right:0cm">After the &quot;<em><strong>Yes</strong></em>&quot; or &quot;<em><strong>No</strong></em>&quot; button is clicked on each widget, information indicating which button was clicked in which window will be printed to the console:</p>

<p style="margin-left:0cm; margin-right:0cm"><span style="font-size:12pt"><span style="font-family:&quot;Times New Roman&quot;"><strong><em>Result: {.mb1 yes } {.mb2 yes } {.mb3 no }</em></strong></span></span></p>

<p style="margin-left:0cm; margin-right:0cm"><span style="font-size:12pt"><span style="font-family:&quot;Times New Roman&quot;">The appearance of information widgets&mdash;like that of all other <strong><em>SVG</em></strong> widgets&mdash;can be customized by specifying various options. For instance, widget stroke properties are defined using the options <strong><em>`-stroke</em></strong>` (stroke color), <strong><em>`-strokewidth</em></strong>` (stroke thickness), and `<strong><em>-strokeopacity</em></strong>` (stroke opacity, ranging from 0.0 to 1.0). Corner rounding is controlled by the <strong><em>`-rx</em></strong>` option. Font characteristics are set via the options <strong><em>`-fontsize</em></strong>` (font size), `<strong><em>-textstroke</em></strong>` (text outline color), and `<strong><em>-textfill</em></strong>` (font color).</span></span></p>

<p style="margin-left:0cm; margin-right:0cm"><span style="font-size:12pt"><span style="font-family:&quot;Times New Roman&quot;">Information widgets of the types *<strong><em>left</em></strong>*, *<strong><em>right</em></strong>*, *<strong><em>up</em></strong>*, *<em>down</em>*, and *<strong><em>none</em></strong>* can have a &quot;<strong><em>tongue</em></strong>&quot; (the `<strong><em>-tongue</em></strong>` option)&mdash;a feature we already encountered when examining the <a href="https://wiki.tcl-lang.org/page/SVG+widgets+Part+2">*<strong><em>cmenu</em></strong>* class widget</a>:</span></span></p>

<p style="margin-left:0cm; margin-right:0cm"><img alt="" src="https://habrastorage.org/webt/c2/fa/3b/c2fa3ba3457c713156b8caeac13bf539.png" style="height:383px; width:850px" /></p>

<p style="margin-left:0cm; margin-right:0cm">Here is the code for this demonstration:</p>

<div>
<div style="background-color:#f7f7f7; border-radius:5px; border:1px solid #0077cc; padding:5px">
<p>package require svgwidgets<br />
set textanchor [list nw n ne]<br />
set mtype [list down up left right none]<br />
set txt &quot;Information for you.\n&quot;<br />
append txt &quot;Click me and\nthe widget will close.\n&quot;<br />
lassign {1 0 0 } i wm hm<br />
set lmsg [list ]<br />
lassign {12 1.0 100 3 2} fsize fopaci x0 grad wstr<br />
set fsize [list 0 10 14 18 22 24]<br />
foreach type $mtype {<br />
&nbsp; &nbsp; set txt1 &quot;[set txt](Type: $type)&quot;<br />
&nbsp; &nbsp; set tfont [lindex $fsize $i]<br />
&nbsp; &nbsp; set msg [mbutton new .mb[set i] -place window -type [set type] -fontsize $tfont -text $txt1 -strokewidth [expr {$wstr * $i}]]<br />
&nbsp; &nbsp; set i1 $i<br />
&nbsp; &nbsp; if {$i1 != 1} {<br />
&nbsp; &nbsp; set i [expr {$i - 0.9}]<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; set opacity [expr {$fopaci / $i}]<br />
&nbsp; &nbsp; $msg config -fillopacity $opacity -fillnormal gradient0 -stroke chocolate<br />
&nbsp; &nbsp; lappend lmsg $msg<br />
&nbsp; &nbsp; set i $i1<br />
&nbsp; &nbsp; incr i<br />
&nbsp; &nbsp; incr grad<br />
}<br />
set i 1<br />
set x1 $x0<br />
foreach m $lmsg {<br />
&nbsp; &nbsp; if {$i &lt; 4 } {<br />
&nbsp; &nbsp; set y0 100<br />
&nbsp; &nbsp; } elseif {$i == 4} {<br />
&nbsp; &nbsp; set y0 250<br />
&nbsp; &nbsp; set x0 [expr {$x1 + 30}]&nbsp;<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; after 0&nbsp; $m place&nbsp; -x $x0 -y $y0<br />
&nbsp; &nbsp; update idletasks<br />
&nbsp; &nbsp; after 100<br />
&nbsp; &nbsp; if {$i &gt; 4} {<br />
&nbsp; &nbsp; break<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; lassign &quot;[[lindex $lmsg $i] config -width] [winfo rootx .mb[set i]]&quot; mw mr<br />
&nbsp; &nbsp; set x0 [expr {$x0 + $mw + $mr + 10}]<br />
&nbsp; &nbsp; incr i<br />
&nbsp; &nbsp; if {$i == 5} {&nbsp;<br />
&nbsp; &nbsp; set x0 [expr {$x0 + 10}]&nbsp;<br />
&nbsp; &nbsp; [lindex $lmsg 4] config -strokeopacity 0.75<br />
&nbsp; &nbsp; }<br />
}<br />
foreach w &quot;.mb1 .mb2 .mb3 .mb4 .mb5&quot; {<br />
&nbsp; &nbsp; if {[winfo exist $w]} {<br />
&nbsp; &nbsp; tkwait window $w<br />
&nbsp; &nbsp; }<br />
}<br />
puts &quot;Ended&quot;</p>
</div>
</div>

<p style="margin-left:0cm; margin-right:0cm"><span style="font-size:12pt"><span style="font-family:&quot;Times New Roman&quot;">Information widgets can be created either in a separate window (<strong><em>toplevel</em></strong>) or on an <strong><em>SVG</em></strong> canvas (<strong><em>tkp::canvas</em></strong>). This placement is specified when the widget is created via the <strong><em>`-place</em></strong>` parameter, which can take the value `<strong><em>window</em></strong>` or `<strong><em>canvas</em></strong>` (the default).</span></span></p>

<p style="margin-left:0cm; margin-right:0cm"><span style="font-size:12pt"><span style="font-family:&quot;Times New Roman&quot;">It is advisable to use the `<strong><em>place</em></strong>` method to position information widgets:</span></span></p>

<p style="margin-left:0cm; margin-right:0cm"><span style="font-size:12pt"><span style="font-family:&quot;Times New Roman&quot;"><strong><em>&lt;ID-mbutton&gt; place -</em></strong><strong><em>x &lt;X-coordinate&gt; -y &lt;Y-coordinate&gt; [-in &lt;window&gt;]</em></strong></span></span></p>

<p style="margin-left:0cm; margin-right:0cm">&nbsp;</p>

<p style="margin-left:0cm; margin-right:0cm"><span style="font-size:12pt"><span style="font-family:&quot;Times New Roman&quot;">To close an *<strong><em>mbutton</em></strong>* widget of the '<strong><em>yesno</em></strong>' or '<strong><em>msg</em></strong>' type, you must click either the &quot;<strong><em>Yes</em></strong>&quot; or &quot;<strong><em>No</em></strong>&quot; button. The returned value will be either &quot;<strong><em>yes</em></strong>&quot; or &quot;<strong><em>no</em></strong>&quot;.</span></span></p>

<p style="margin-left:0cm; margin-right:0cm">Complete the following example:</p>

<div class="row">
<div>
<div style="background-color:#f7f7f7; border-radius:5px; border:1px solid #0077cc; padding:5px">
<p>package require svgwidgets<br />
set textanchor [list none nw n ne]<br />
set mtype [list yesno msg yesno]<br />
set txt &quot;\nAre you sure\n&quot;<br />
append txt &quot;sure your choice is correct\n&quot;<br />
append txt &quot;?\n&quot;<br />
lassign {1 0 0 } i wm hm<br />
set lmsg [list ]<br />
lassign {12 1.0 10 3 2} fsize fopaci x0 grad wstr<br />
set mret [list]<br />
toplevel .mb -bg yellow<br />
wm geometry .mb 700x400+200+50<br />
foreach type $mtype {<br />
&nbsp; &nbsp; set ta [lindex $textanchor $i]<br />
&nbsp; &nbsp; set msg [mbutton new .mb.mb[set i] -place canvas -type [set type] -fontsize [expr {$fsize * $i}] -text $txt -strokewidth [expr {$wstr * $i}] -textanchor [set ta]]<br />
&nbsp; &nbsp; $msg config&nbsp; -fillopacity [expr {$fopaci / $i}] -fillnormal gradient[set grad]<br />
&nbsp; &nbsp; lappend lmsg $msg<br />
&nbsp; &nbsp; set mw [winfo width .mb.mb[set i]]<br />
&nbsp; &nbsp; set mr [winfo rootx .mb.mb[set i]]<br />
&nbsp; &nbsp; set x0 [expr {$x0 + $mw + 40}]<br />
&nbsp; &nbsp; incr i<br />
&nbsp; &nbsp; incr grad<br />
&nbsp; &nbsp; update idletasks<br />
&nbsp; &nbsp; after 300<br />
&nbsp; &nbsp; set xx[set i] [$msg place -x $x0 -y 50 ]<br />
&nbsp; &nbsp; lappend mret [set xx[set i]]<br />
}<br />
puts &quot;\nReturn: $mret\n&quot;<br />
destroy .mb</p>
</div>
</div>

<div class="row"><br />
and you will see how it works:</div>

<div class="row">&nbsp;</div>

<div class="row"><img alt="" src="https://habrastorage.org/webt/25/cb/9e/25cb9e1acf54363d2a0d5c927b293384.png" style="height:399px; width:850px" /></div>
</div>

<p style="margin-left:0cm; margin-right:0cm"><span style="font-size:12pt"><span style="font-family:&quot;Times New Roman&quot;">To align text within the widget, the <strong><em>`-textanchor</em></strong>` option is used; it can take one of the values <span style="font-family:&quot;Arial Unicode MS&quot;">​​</span>`<strong><em>nw</em></strong>`, `<strong><em>n</em></strong>`, or `<strong><em>ne</em></strong>` (see the `<strong><em>textanchor</em></strong>` variable in the example).</span></span></p>

<p style="margin-left:0cm; margin-right:0cm"><span style="font-size:12pt"><span style="font-family:&quot;Times New Roman&quot;">To close other types of widgets, simply click on them. </span></span></p>

<p style="margin-left:0cm; margin-right:0cm"><span style="font-size:12pt"><span style="font-family:&quot;Times New Roman&quot;">The code below demonstrates this:</span></span></p>

<div>
<div style="background-color:#f7f7f7; border-radius:5px; border:1px solid #0077cc; padding:5px">
<p>package require svgwidgets<br />
set textanchor [list nw n ne]<br />
set mtype [list down up left right none]<br />
set txt &quot;Information for you.\n&quot;<br />
append txt &quot;Click me and\nthe widget will close.\n&quot;<br />
lassign {1 0 0 } i wm hm<br />
set lmsg [list ]<br />
lassign {12 1.0 10 3 2} fsize fopaci x0 grad wstr<br />
set mret [list]<br />
toplevel .mb -bg yellow<br />
wm geometry .mb 700x400+200+50<br />
cbutton create fr .mb.fr -type frame -bg gray80 -fillnormal gradient2<br />
pack .mb.fr -fill both -expand 1<br />
update<br />
after 300<br />
set fsize [list 10 14 18 22 24 28]<br />
foreach type $mtype {<br />
&nbsp; &nbsp; set txt1 &quot;[set txt](Type: $type)&quot;<br />
#&nbsp; &nbsp; set msg [mbutton new .mb.mb[set i] -place canvas -type [set type] -fontsize [expr {$fsize * $i / 2.0}] -text [set txt1] -strokewidth [expr {$wstr * $i}]]<br />
&nbsp; &nbsp; set msg [mbutton new .mb.mb[set i] -place canvas -type [set type] -fontsize [lindex $fsize $i] -text [set txt1] -strokewidth [expr {$wstr * $i}]]<br />
#&nbsp; &nbsp; $msg config&nbsp; -fillopacity [expr {$fopaci / $i}] -fillnormal gradient[set grad]<br />
#&nbsp; &nbsp; $msg config&nbsp; -fillopacity [expr {$fopaci / $i}] -fillnormal cyan<br />
&nbsp; &nbsp; $msg config&nbsp; -fillopacity [expr {1.5 * $fopaci / $i}] -fillnormal gradient0<br />
&nbsp; &nbsp; lappend lmsg $msg<br />
&nbsp; &nbsp; set mw [winfo width .mb.mb[set i]]<br />
&nbsp; &nbsp; set mr [winfo rootx .mb.mb[set i]]<br />
&nbsp; &nbsp; set x0 [expr {$x0 + $mw + 40}]<br />
&nbsp; &nbsp; incr i<br />
&nbsp; &nbsp; incr grad<br />
&nbsp; &nbsp; update idletasks<br />
#&nbsp; &nbsp; after 300<br />
&nbsp; &nbsp; set xx[set i] [$msg place -x $x0 -y 50 -in .mb.fr ]<br />
&nbsp; &nbsp; lappend mret [set xx[set i]]<br />
}<br />
puts &quot;\nReturn: $mret\n&quot;<br />
fr destroy<br />
destroy .mb</p>

<p>&nbsp;</p>
</div>
</div>

<p style="margin-left:0cm; margin-right:0cm"><img alt="" src="https://habrastorage.org/webt/23/e9/34/23e9340ae4b5d58b508619a8a8a9daee.png" style="height:438px; width:850px" /></p>

<p style="margin-left:0cm; margin-right:0cm"><span style="font-size:12pt"><span style="font-family:&quot;Times New Roman&quot;">In conclusion, a new version of the <a href="https://github.com/tcltk-depot/tkpath"><strong><em>tkpath</em></strong> package</a> &mdash; a core package for <strong><em>SVG</em></strong> widgets&mdash;has been released. Version 0.4.3 of <strong><em>tkpath</em></strong> (`<strong><em>package require tkpath 0.4.3</em></strong>`) includes the `<strong><em>tkp::loupe</em></strong>` function, making it possible to avoid using the <strong><em>treectrl</em></strong> package when using the <strong><em>svgwidgets</em></strong> package:</span></span></p>

<div>
<div style="background-color:#f7f7f7; border-radius:5px; border:1px solid #0077cc; padding:5px">
<p>if {[catch {package require tkpath}]} {<br />
&nbsp; &nbsp; package require tko<br />
}<br />
if {[info command ::tkp::loupe] == &quot;&quot;} {<br />
&nbsp; &nbsp; package require treectrl<br />
}</p>
</div>
</div>

<p>&nbsp;</p>

<p>&nbsp;</p>
</div>
</div>

<<inlinehtml>>

<<categories>> Useful Tk Widgets | Arts and Crafts of Tcl-Tk Programming | GUI