if 0 {
MiHa 2015-05-13: This is a demo for a tcl/tk-program with all the essential GUI-elements.
It acts as a simple invoice-program with menu, entry-form and output (planned: one printed page).
All the data is just strings of text, no validation, no calculation.
With ideas and code from the following pages:
}
# InvoiceDemo07.tcl - Mike Hase - 2015-05-19 # http://wiki.tcl.tk/29284 # Simple "invoice"-themed GUI-demo, with menu, form for data-entry, output to screen and printer. # (output to printer is not done yet) package require Tk set Prog(Title) "Invoice-Demo" set Prog(Version) "v0.07" set Prog(Date) "2015-05-20" set Prog(Author) "Mike Hase" set Prog(Contact) "[email protected]" set Prog(About) "A GUI-demo (disguised as an invoice-program:)\nPlus a printer-test." #---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+ global data maxFNr set FieldNames1 {"Date " Title Name Street City Phone} #set FieldNames2 { art1Nr art1qty art1desc art1price price1} set FieldNames2 { Article-Number Quantity Description Price Total} set fNr 0 set artNr 0 # Build data-entry form: ## Todo: put this form into its own dialog #: Frame for customer-data: frame .f1 ;# -background red set hdr [label .f1.lbHdr -text "Customer:"] grid $hdr -columnspan 2 -pady 8 foreach field $FieldNames1 { incr fNr set data($fNr) $fNr ;## Test set lb [label .f1.lb$field -text $field] set en [entry .f1.en$field -justify left -textvar data($fNr) ] grid $lb $en -padx 4 -pady 2 grid $lb -sticky e grid $en -sticky ew } #: Frame for article-data: # Same layout as above. Todo: place all fields for an article in one line frame .f2 ;# -background green incr artNr ;# Todo: extend to more articles set hdr [label .f2.hdr -text "Purchase:"] grid $hdr -columnspan 2 -pady 8 foreach field $FieldNames2 { incr fNr set data($fNr) $fNr ;## set lb [label .f2.lb$field -text $field] set en [entry .f2.en$field -justify right -textvar data($fNr) ] grid $lb $en -padx 4 -pady 2 grid $lb -sticky e grid $en -sticky ew } set maxFNr $fNr if 0 { ;# these buttons can be used as an alternative to the m+menu #: Frame for buttons: frame .f8 -background blue button .f8.b1 -text New -command { data0 } button .f8.b2 -text Test1 -command { data1 } button .f8.b3 -text Test2 -command { data2 } button .f8.b4 -text Show -command { showData } button .f8.b5 -text Print -command { printData } button .f8.b6 -text Exit -command { exit } grid .f8.b1 .f8.b2 .f8.b3 .f8.b4 .f8.b5 .f8.b6 pack .f1 .f2 .f8 -side top } pack .f1 .f2 -side top #---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+ # Menu: proc m+ {head name {cmd ""}} { #: Menu-creator "m+" by R.Suchenwirth and DKF, 2006-08-24, see http://wiki.tcl.tk/16327 # Uses the undocumented and unsupported feature ::tk::UnderlineAmpersand if {![winfo exists .m.m$head]} { foreach {l u} [::tk::UnderlineAmpersand $head] break .m add cascade -label $l -underline $u -menu [menu .m.m$head -tearoff 0] } if {[regexp ^-+$ $name]} { .m.m$head add separator } else { foreach {l u} [::tk::UnderlineAmpersand $name] break .m.m$head add command -label $l -underline $u -comm $cmd } } # GUI: define menu, bindings . configure -menu [menu .m] m+ &File &Open { Dummy "Open" } m+ &File &Save { Dummy "Save" } m+ &File ----- m+ &File &Exit exit m+ &Edit &Clear data0 m+ &Edit Testdata&1 data1 m+ &Edit Testdata&2 data2 m+ &Output &List showData m+ &Output &Print printData m+ &Help &About About m+ &Help &Help Help m+ &Help ----- m+ &Help &Debug { console show } bind all <Key-F1> About bind all <Key-F2> { console show } bind all <Key-F4> exit bind all <Key-F5> data0 bind all <Key-F6> data1 bind all <Key-F7> data2 bind all <Key-F8> showData #---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+ proc Dummy {txt} { #: Alert: "Function X not implemented yet" bell tk_messageBox -icon warning -title "Demo" \ -message "Function '$txt' not implemented yet." } proc About {} { #: Short info about the program global Prog set txt "$Prog(Title) $Prog(Version) - " append txt "$Prog(Date)\nby $Prog(Author) - $Prog(Contact)\n\n$Prog(About)" tk_messageBox -icon info -message $txt -title "About $Prog(Title) $Prog(Version)" } proc Help {} { Dummy Help } ;# needs work #---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+ # Routines to edit/fill in data: proc data0 {} { #: Clear data in entry-fields for {set f 1} {$f <= $::maxFNr} {incr f} { set ::data($f) "" } } proc data1 {} { #: Fill entry-fields with testdata set ::data(1) "2015-05-13" set ::data(2) "Mr." set ::data(3) "Smith" set ::data(4) "Mainstreet 123" set ::data(5) "Newtown" set ::data(6) "555-6789" set ::data(7) "0815" set ::data(8) "2" set ::data(9) "T-Shirt" set ::data(10) " 9.99" set ::data(11) "19.98" } proc data2 {} { #: Fill entry-fields with testdata set fNr 0 set values { "2015-05-14" "Mrs." "Miller" "Highstreet 99" "Oldsville" "555-9876" "0816" "1" "T-Shirt XL" "12.34" "12.34" } foreach v $values { incr fNr set ::data($fNr) $v } } #---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+ # Output-Routines: proc listData {} { #: Show the data on the console global data maxFNr puts "INVOICE\n==" for {set f 1} {$f <= $maxFNr} {incr f} { puts "Field#$f : $data($f)" } puts "--\nTHANKS !" } proc showData {} { #: Show the data in a simple messagebox global data maxFNr set txt "INVOICE\n==\n" for {set f 1} {$f <= $maxFNr} {incr f} { append txt "Field#$f : $data($f)\n" } append txt "--\nTHANKS !" tk_messageBox -icon info -message $txt -title "ShowData" } # Todo: proc printData {} { Dummy printData } #---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+ #: Test+Debug: proc ? {} { help } proc help {} { puts "\n$::Prog(Title) $::Prog(Version)" puts "--" puts "argv0 : $::argv0" puts "argv : $::argv" puts "tcl/tk: $::tcl_patchLevel / $::tk_patchLevel \n" puts "d0,d1,d2,s,l:data0,data1,data2,listData,showData ?:help e:exit \n" } proc d0 {} { data0 } proc d1 {} { data1 } proc d2 {} { data2 } proc l {} { listData } proc s {} { showData } proc e {} { exit } #---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+ #: Main: wm title . "$Prog(Title) $Prog(Version)" help # Todo: make and include an icon here if {[file exists demo.ico]} { wm iconbitmap . demo.ico } focus -force . ### EOF ###
Example icon: InvoiceDemo_icon
It looks like the upload-procedure of the wiki doesn't like .ico - files.
So, just copy any icon you like to the location of the program, and rename it to demo.ico
Dump of the contents of the entry-fields, filled with testdata:
INVOICE == Field#1 : 2015-05-13 Field#2 : Mr. Field#3 : Smith Field#4 : Mainstreet 123 Field#5 : Newtown Field#6 : 555-6789 Field#7 : 0815 Field#8 : T-Shirt ultrablack, size XL Field#9 : 9.99 Field#10 : 2 Field#11 : 19.98
MiHa: This is a nice small demo of a simple program using only basic, essential GUI-features:
There is lots of more advanced GUI-stuff not covered so far, e.g.:
But if any of that gets included, and the program gets more complex,
it might be better to put that into a separate program.
The data is just simple strings of text, all of the same length, no validation, no calculation, no special logic, etc.
This definitely needs work for any real-world application.
BTW, I haven't found yet any good, nice, short routine for data-entry (such as m+ for menus).
Also, there is no file-I/O for data or configuration.
I haven't looked into the printing stuff yet, so if anybody thinks he is up to the task, you are welcome to fill in that part.
All in all, it looks like printing from Tcl/tk in a "native, portable way" is kind of a hard problem, and still mostly unsolved.