📜 ⬆️ ⬇️

Tcl / Tk. Thematic TTK widgets and designer TKproE-2.20

image Looking through my notes on GUI design using Tk widgets, I felt some sort of dissatisfaction. And the thing turned out to be that I actually missed the work with thematic widgets ttk (themed tk). They were casually involved when reviewing the Tkinter package for Python and using the Page designer. It was about the TNotebook widget (notepad, notebook) from the ttk package.

The TNotebook widget is one of the new widgets, along with TCombobox, TProgressbar, TSeparator and TSizegrip, which appeared in ttk. Converting applications from classic tk to ttk may require minimal effort. Sometimes it is enough instead of, for example, button to write ttk :: buton. Separately, I want to say about the combobox. If you used a spinbox widget in your applications written in tk and now replace it with ttk :: combobox, then the application will display this widget that you missed so much:

image

But nevertheless the main thing in ttk, it is not new widgets, but their design (ited). Customizing themes styles deserves a separate discussion. And here I would send the developers to the wonderful tutorial published just a few days ago (11.11.2017):
')
image

Despite the fact that it is written in German, but I do not even know English, I read it with great pleasure. As they say, written for the "fool."

We are interested in whether there is an integrated development environment / designers for ttk widgets. If we talk about Python and Tkinter, then this is the Page package . This package supports both classic widgets and theme widgets. True, for some reason, there is no support for TSeparator separators. The design environment is the Tcl scripting language. It is for this reason that we will return to this package. Note the undoubted advantage of Page is the presence of an easel on which you can easily and conveniently place widgets.

But this is for Python, and we are interested in the final product on Tcl. It turned out that exactly one year ago (November 27, 2016), Tcl / Tk designer TKproE 2.20 was announced :

image

And there are TSeparator separators in it. A unique feature of this designer is that it accepts almost any tcl / tk script.
To demonstrate the capabilities of both ttk widgets and TKproE-2.20 designer, a GUI interface was developed for the pp “elegant print” utility from the NSS package with eliminated jambs and support for Russian pki (public key infrastructure) oid. Moreover, such a utility for viewing certificates, including qualified certificates , viewing the electronic signature of a document, is in demand. And it was for her that the graphical interface was designed and implemented using TKproE:

image

Utility and graphic binding to it can be downloaded here . Another very pleasant surprise, unlike other designers, was waiting when working with image (image) and icons. If earlier it was necessary to “transfer” the image to PEM-encoding and insert the code into the script itself, now it is enough to specify the image file and TKproE will take it and convert it:

image

The only inconvenience here is the need to enter the file name. But it turned out to be easy to fix. It is enough in the tkproe.tc l script in lines 7474 and 7516 code (procedure proc ShowWindow.tpimages )

label .tpimages.propbitmap.frame14.label12 -activebackground {#dcdcdc} \ -anchor {w} - background {#dcdcdc} -borderwidth {2} -font {Helvetica 10} \ -highlightbackground {#dcdcdc} -text {File:} -width {10} 

replace with code:

 button .tpimages.propbitmap.frame14.label12 -activebackground {#dcdcdc} \ -anchor {w} -background {#dcdcdc} -borderwidth {2} -font {Helvetica 10} \ -highlightbackground {#dcdcdc} -text {File:} -width {10} \ -command { global userDir; set fileTypes {{"File image" *}}; \ set file [tk_getOpenFile -title "Find Image" -filetypes $fileTypes \ -initialdir "$userDir"]; \ .tpimages.propphoto.frame14.entry13 delete 0 end; \ .tpimages.propphoto.frame14.entry13 insert end $file; } 

To make the file selection start from the home directory after line 5, add the following code to the tkproe.tcl script:

 global userDir set userDir $env(HOME) 

Now, to select a file with an image, simply click the “File:” button:

image

Those interested can improve this code, for example, fill in the “Format” field by the selected file, or vice versa, organize the file search by format, considering the format as a file extension (“File type” in the screenshot).

Another inconvenience that I had to face was getting the user's home directory, for example, mHOME set $ env (HOME). And the home directory, as a rule, is needed to provide a platform independent script. It turned out through TKproE insert it nowhere. Global variables in TKproE are defined through the TPinitVars procedure. Naturally, if you define the mHOME variable through the field of global variables:

image

then the mHome variable will have the value "$ env (HOME)". It would seem, take and insert the calculation of the current directory handles in the main body of the script. You can, if only you no longer edit the script in TKproE. Otherwise, TKproE will take care of the optimization and instead of the set nHOME code $ env (HOME) will insert the code with the home directory of the computer on which the script was created / corrected into the procedure of global variables initialization. It's horrible.

It had to climb into the code TKproE for the second time. We found a way out of this situation in the definition of the global variable myHOME and the inclusion of additional code in the generated script. And so, in the proc TP_Clone_app procedure immediately following the line (13th):

 set outstr "# Generated by TKproE $TPinfo(revision) - [clock format [clock seconds]]\n\n" 

add row

 append outstr "#Add me\nencoding system utf-8\nglobal myHOME\nset myHOME \$env(HOME)\n\n" 

and in the proc TP_Clone_variables procedure after the line (10th)

  foreach varname $varlist { 

insert code

 if { $varname == "myHOME" } { continue } 

which disables the resetting of the myHOME global variable.

And after these improvements, we managed to create a graphical shell for the PP utility:

image

If you select the file with the document and click the "Show in window" button, we will see the following:

image

A certificate printout, like any other document, can be saved in a file (the “Save to file” button on the “Certificates, etc.” tab).
The GUIPP script source code, which is also the TKproE project, can be downloaded here .

Above, we talked about going back to the Page designer. In the Page designer it is very convenient to design a GUI with free placement of widgets (place). As already mentioned, the GUI Project Page designer stores as a Tcl / Tk script, and it would be tempting to use a ready-made script from Page in TKproE or to add it manually. In its pure form, the project from Page cannot be executed or loaded into TKproE-2.20. To eliminate this “injustice”, a tcl script was developed, which leads projects from Page to tcl / tk scripts to be executed:

 sh-4.3$ ./fromPageToTcl.tcl Usage: ./fromPageToTcl.tcl <file tcl from Page> sh-4.3$ 

Here is the code for the tcl script fromPageToTcl.tcl:

Tcl script code fromPageToTcl.tcl
 #!/usr/bin/tclsh # 1 -- source file #   return # if {[winfo exists $base]} { #### wm deiconify $base; return # } #   ## vTcl:FireEvent $base <<Ready>> #LISSI-Soft namespace eval vTcl::widgets::ttk::sizegrip { proc CreateCmd {target args} { grid [ttk::sizegrip $target] -column 999 -row 999 -sticky se } } proc vTcl:font:add_GUI_font {font_name font_descr} { # This is called when we load an existing GUI-tcl file. It get rid # of actual fonts and replaces them with the definitions from the # GUI-tcl file. #set font_descr [font configure $font_name] if {[catch { font delete $font_name set newfont [font create $font_name {*}$font_descr ] } result]} { # Create failed set newfont "TkDefaultFont" } #set newkey NEEDS WORK #set ::vTcl(fonts,$newfont,type) $font_type #set ::vTcl(fonts,$newfont,key) $newkey set ::vTcl(fonts,$newfont,font_descr) $font_descr set ::vTcl(fonts,$font_descr,object) $newfont ;# Rozen 8/24/13 #set ::vTcl(fonts,$newkey,object) $newfont } proc {vTcl:font:add_font} {font_descr font_type {newkey {}} {check_fonts {1}}} { global vTcl ## This procedure may be used free of restrictions. ## Exception added by Christian Gavin on 08/08/02. ## Other packages and widget toolkits have different licensing requirements. ## Please read their license agreements for details. # With tk you are not allowed to specify the the font name when # creating a fomt. So if you want to assign a name to a font then # specify then the variable ::vTcl(fonts,$newkey,object) will hold # the correspondance between the actual name of the created name # and the name you wish to use. Rozen set defined_fonts [font names] if {$newkey != ""} { if {[info exists ::vTcl(fonts,$font_descr,object)]} { set test_font $::vTcl(fonts,$font_descr,object) if {[lsearch $defined_fonts $newkey] == -1} { set ::vTcl(fonts,$newkey,object) $test_font return $test_font } } } if {$check_fonts} { if {[info exists ::vTcl(fonts,$font_descr,object)]} { # It already exists return $::vTcl(fonts,$font_descr,object) } if {[lsearch $defined_fonts $font_descr] > -1} { # It's a font already defined.. return $font_descr } } incr ::vTcl(fonts,counter) set newfont [eval font create $font_descr] lappend ::vTcl(fonts,objects) $newfont ## each font has its unique key so that when a project is ## reloaded, the key is used to find the font descriptio if {$newkey == ""} { set newkey vTcl:font$::vTcl(fonts,counter) ## let's find an unused font key while {[vTcl:font:get_font $newkey] != ""} { incr ::vTcl(fonts,counter) set newkey vTcl:font$::vTcl(fonts,counter) } } set ::vTcl(fonts,$newfont,type) $font_type set ::vTcl(fonts,$newfont,key) $newkey set ::vTcl(fonts,$newfont,font_descr) $font_descr set ::vTcl(fonts,$font_descr,object) $newfont set ::vTcl(fonts,$newkey,object) $newfont lappend ::vTcl(fonts,$font_type) $newfont ## in case caller needs it return $newfont } proc vTcl:DefineAlias {abcde} { # puts \"$a.$b\" # puts \"$c.$d.$e\" return } proc Window {type w} { if {$w == "."} { return } toplevel $w set base $w vTclWindow$w $base } #END LISSI-Soft set largv [llength $argv] if {$largv != 1} { puts "Usage: [info script] <file tcl from Page>\n" exit } set fconf [file exists "$argv"] if { $fconf == "0" } { puts "File=\"$argv\" don't exist\n" puts "Usage: [info script] <file tcl from Page>\n" exit } set srcMy [info script] set fp [open $srcMy r] while {![eof $fp]} { gets $fp res puts $res if { $res == "#END LISSI-Soft"} { break } } close $fp #   Page set fp [open $argv r] while {![eof $fp]} { gets $fp res if { [string first "wm deiconify \$base; return" $res] != -1 } { puts "#LISSI-Soft" puts "\t\twm deiconify \$base;" continue } if { [string first "vTcl:FireEvent \$base <<Ready>>" $res] != -1 } { puts "#LISSI-Soft" puts "#\tvTcl:FireEvent \$base <<Ready>>" continue } </spoiler> if { [string first "vTcl:toplevel \$top -class Toplevel \\" $res] != -1 } { puts "#LISSI-Soft" puts "#vTcl:toplevel \$top -class Toplevel \\" puts "\$top configure \\" continue } if { [string first "vTcl::widgets::core::toplevel::createCmd \$top -class Toplevel \\" $res] != -1 } { puts "#LISSI-Soft" puts "#vTcl::widgets::core::toplevel::createCmd \$top -class Toplevel \\" puts "\$top configure \\" continue } puts $res } close $fp exit 


And so, take an example from the ~ / page / examples / complex folder and get the executable tcl script via the fromPageToTcl.tcl script:

 sh-4.3$cd ~/page/examples/complex sh-4.3$ ./fromPageToTcl.tcl complex.tcl > complex_new.tcl sh-4.3$ 

Now, to get a really good code, open the complex_new.tcl script in the TKproE-2.20 designer and remove all the unnecessary procedures from the project now, and this is the Window procedure and all procedures with the vTcl prefix, and resave it:

image

Note that Page supports more “Scrolled widgets”, we naturally do not support them.

In general, the designer TKproE left a very good impression and it’s nice to work with him on GUI development. The Page x TKproE x fromPageToTcl.tcl trio, consisting of Page designers, TKproE designers and the fromPageToTcl.tcl script, is simply a great trio.

Source: https://habr.com/ru/post/343930/


All Articles