Full listing

This section contains a full listing of the address book application, as it should look in your program. This is a basic data entry application that highlights many of the functionalities of the Tcl/Tk language. At this point, you may wish to sort the dictionary to provide an alphabetical listing of the data, implement multiple field search capability, and toggle the state of the buttons and menu entries to limit the user's abilities in a logical manner or anything else you might want to add.

It's all there in Tcl/Tk. The only limit is your imagination.

# Source the Tk Package
package require Tk
#Configure the Window
wm title . "Address Book"
# Main Frame
frame .main -borderwidth 1 -relief solid -padx 10 -pady 10
# Entry Widgets
entry .main.efirst -width 25
entry .main.elast -width 25
entry .main.eaddress -width 50
entry .main.ecity -width 25
entry .main.estate -width 3
entry .main.ezip -width 5
entry .main.ephone -width 25
# Label Widgets
label .main.first -text "First Name"
label .main.last -text "Last Name"
label .main.address -text "Address"
label .main.city -text "City"
label .main.state -text "ST"
label .main.zip -text "Zip"
label .main.phone -text "Phone"
label .main.photo -text "Click to Update" -width 15
# Label for Photo Widget
label .main.picture -background black
# -width 15 -height 10
# Button Widgets
button .main.previous -text "Previous" -width 15 -command previousRecord
button .main.next -text "Next" -width 15 -command nextRecord
button .main.add -text "Add" -width 15 -command addRecord
button .main.save -text "Save" -width 15 -command saveRecord
button .main.delete -text "Delete" -width 15 -command deleteRecord
button .main.exit -text "Exit" -width 15 -command exit
# Pack command
pack .main
# Grid command
grid .main.efirst -row 0 -column 0 -sticky nw
grid .main.elast -row 0 -column 1 -columnspan 2 -sticky nw
grid .main.picture -row 0 -column 3 -rowspan 7 -sticky news
grid .main.first -row 1 -column 0 -sticky nw
grid .main.last -row 1 -column 1 -columnspan 2 -sticky nw
grid .main.eaddress -row 2 -column 0 -columnspan 3 -sticky nw
grid .main.address -row 3 -column 0 -columnspan 3 -sticky nw
grid .main.ecity -row 4 -column 0 -sticky nw
grid .main.estate -row 4 -column 1 -sticky nw
grid .main.ezip -row 4 -column 2 -sticky nw
grid .main.city -row 5 -column 0 -sticky nw
grid .main.state -row 5 -column 1 -sticky nw
grid .main.zip -row 5 -column 2 -sticky nw
grid .main.ephone -row 6 -column 0 -columnspan 2 -sticky nw
grid .main.phone -row 7 -column 0 -columnspan 2 -sticky nw
grid .main.photo -row 7 -column 3 -sticky nw
grid .main.previous -row 8 -column 0 -sticky ne
grid .main.next -row 8 -column 2 -sticky nw
grid .main.add -row 9 -column 0 -sticky ne
grid .main.save -row 9 -column 1 -sticky nw
grid .main.delete -row 9 -column 2 -sticky nw
grid .main.exit -row 9 -column 3 -sticky nw
# Menu Creation
menu .menubar
.configure -menu .menubar
# Add the first item
set File [menu .menubar.myfile]
.menubar add cascade -label File -menu .menubar.myfile

# Add entries
$File add command -label "Add Record" -command addRecord
$File add command -label "Save Record" -command saveRecord
$File add command -label "Delete Record" -command deleteRecord
$File add separator
$File add command -label "Quit" -command exit
set Edit [menu .menubar.myedit]
.menubar add cascade -label Edit -menu .menubar.myedit

$Edit add command -label "Find" -command findRecord

# Bind the mouse click to the picture label
bind .main.picture <B1-ButtonRelease> getPicture
# Global Variables
# Text file containing stored records
global addressFile
# Dictionary used for working with records
global addressInfo
# Current Record
global currentRecord
# Record Count
global recordCount
# Image File location
global pictureFile
set addressFile "address.txt"
#########################################
# Procedures #
#########################################
proc findRecord { } {
	set strLast ""
	toplevel .find
	frame .find.f -borderwidth 1 -relief solid -padx 10 -pady 10
	entry .find.f.e -borderwidth 5 -relief solid
	button .find.f.ok -text "Find" -command {set strLast [.find.f.e 
get]; lookup $strLast}
	button .find.f.cancel -text "Cancel" -command {destroy .find}
	
	pack .find.f
	grid .find.f.e -row 0 -column 0 -columnspan 2 -sticky news
	grid .find.f.ok -row 1 -column 0 -sticky news
	grid .find.f.cancel -row 1 -column 1 -sticky news
}
proc lookup {strLast} {
	global addressInfo
	global currentRecord
	puts "LOOKING for $strLast"
		dict for {id info} $addressInfo {
			dict with info {
				if {"$strLast" == "$LNAME"} {
				puts "NAME: $LNAME"
				puts "FOUND ONE"
				set currentRecord "$ID"
				clearRecord
				loadRecord
			}
		}
	}
}
# This procedure is used to load and display a record
# from the dictionary
proc loadRecord { } {
	global currentRecord
	global addressInfo
	.main.efirst insert 0 [dict get $addressInfo $currentRecord FNAME]
	.main.elast insert 0 [dict get $addressInfo $currentRecord LNAME]
	.main.eaddress insert 0 [dict get $addressInfo $currentRecord 
	ADDRESS]
	.main.ecity insert 0 [dict get $addressInfo $currentRecord CITY]
	.main.estate insert 0 [dict get $addressInfo $currentRecord STATE]
	.main.ezip insert 0 [dict get $addressInfo $currentRecord ZIP]
	.main.ephone insert 0 [dict get $addressInfo $currentRecord PHONE]

	# Load the photo
	if {[dict get $addressInfo $currentRecord PHOTO] > 0} {
		set pictureFile [dict get $addressInfo $currentRecord PHOTO]
		image create photo addressPhoto -file $pictureFile
		.main.picture configure -image addressPhoto
	}
}
proc clearRecord {} {
	.main.efirst delete 0 end
	.main.elast delete 0 end
	.main.eaddress delete 0 end
	.main.ecity delete 0 end
	.main.estate delete 0 end
	.main.ezip delete 0 end
	.main.ephone delete 0 end
	.main.picture configure -image ""
}
proc addRecord {} {
	global currentRecord
	global recordCount
	global addressInfo
	global pictureFile
	# Clear current entries
	clearRecord
	set pictureFile ""
	set currentRecord [expr $recordCount +1]
}
proc nextRecord {} {
	global currentRecord
	global recordCount

	if { $currentRecord < $recordCount } {
		# Clear current entries
		clearRecord

		incr currentRecord
		loadRecord
	}
}
proc previousRecord {} {
	global currentRecord
	global recordCount
	if { $currentRecord > 1 } {
		# Clear current entries
		clearRecord
		
		set currentRecord [expr $currentRecord - 1]
		loadRecord
	}
}
proc saveRecord {} {
	global currentRecord
	global recordCount
	global addressFile
	global addressInfo
	global pictureFile
	# No Records Exist
	if {$currentRecord == 0} {
		incr currentRecord
		incr recordCount
	}
	dict set addressInfo $currentRecord ID "$currentRecord"
	dict set addressInfo $currentRecord FNAME "[.main.efirst get]"
	dict set addressInfo $currentRecord LNAME "[.main.elast get]"
	dict set addressInfo $currentRecord ADDRESS "[.main.eaddress get]"
	dict set addressInfo $currentRecord CITY "[.main.ecity get]"
	dict set addressInfo $currentRecord STATE "[.main.estate get]"
	dict set addressInfo $currentRecord ZIP "[.main.ezip get]"
	dict set addressInfo $currentRecord PHONE "[.main.ephone get]"
	dict set addressInfo $currentRecord PHOTO "$pictureFile"

	# Write the records to the file

	set fp [open $addressFile w+]
	
	dict for {id info} $addressInfo {
		dict with info {
			# Create an entry for the file
			set data "$ID,$FNAME,$LNAME,$ADDRESS,$CITY,$STATE,$ZIP, 
$PHONE,$PHOTO
"
			# Write the entry to the file
			puts -nonewline $fp $data
			}
		}
		set recordCount [dict size $addressInfo]
		# Close the file
		close $fp
}
proc deleteRecord {} {
	global addressFile
	global addressInfo
	global currentRecord
	global recordCount

	if {$recordCount > 0} {
		set myTitle "Confirm Request"
		set myMessage "Select OK to delete the current record"
		set response [tk_messageBox -message $myMessage 
			-title myTitle 
			-type okcancel 
			-icon warning]

		if {$response == "ok"} {
			puts "DELETE COUNT: $recordCount CURRENT: $currentRecord"
			set tempDict [dict remove $addressInfo $currentRecord]
			clearRecord
			puts "IN DELETE"
			set fp [open $addressFile w+]
			puts "DELETE FILE ID: $fp"
			set recnum 0	

			dict for {id info} $tempDict {
				dict with info {
					incr recnum
					# Create an entry for the file
					set data "$recnum,$FNAME,$LNAME,$ADDRESS,$CITY, 
					$STATE, $ZIP,$PHONE,$PHOTO
"
					puts "---"
					puts "NEW DATA: $data"
					# Write the entry to the file
					puts -nonewline $fp $data
				}
			}
			flush $fp
			close $fp

			puts "POST DELETE FILE WRITE - READING IN NEW FILE"

			# Clean up the dictionary files
			unset addressInfo
			unset tempDict
			# If we deleted the last record this avoids trying to read in an 
				empty file
			if {[file size $addressFile] > 0} {
				set fp [open $addressFile r+]
				fconfigure $fp -buffering line
				gets $fp data

				set recno 0
				while { $data > 0 } {
					puts "DATA ADDED TO DICT: $data TO RECNO: $recno"
					set data2 [split $data ","]

					incr recno

					dict set addressInfo $recno ID [lindex $data2 0]
					dict set addressInfo $recno FNAME [lindex $data2 1]
					dict set addressInfo $recno LNAME [lindex $data2 2]
					dict set addressInfo $recno ADDRESS [lindex $data2 3]
					dict set addressInfo $recno CITY [lindex $data2 4]
					dict set addressInfo $recno STATE [lindex $data2 5]
					dict set addressInfo $recno ZIP [lindex $data2 6]
					dict set addressInfo $recno PHONE [lindex $data2 7]
					dict set addressInfo $recno PHOTO [lindex $data2 8]
					set pictureFile [dict get $addressInfo $recno PHOTO]
					gets $fp data
					}

				set recordCount [dict size $addressInfo]
				puts "NEW addressInfo recordCount $recordCount

"
				set currentRecord 1

				# Load the first record
				loadRecord
			} else {
				set myTitle "Missing Records"
				set myMessage "No records exist, please add an entry and click save"
				tk_messageBox -message $myMessage 
				-title $myTitle 
				-type ok 
				-icon warning
				set currentRecord 0
				set recordCount 0
				set pictureFile ""	
			}
		}
	}
}
proc getPicture {} {
	global currentRecord
	global addressInfo
	global pictureFile

	set types {
		{{GIF} {.gif} }
		{{PPM} {.ppm} }
		{{All Files} * }
	}
	set filename [tk_getOpenFile -filetypes $types]
	
	if {$filename != ""} {
		# Now that we have the path to the desired picture
		# we copy it to the working directory
		# Get the destination filename
		# by splitting the fullpath into
		# elements and retrieving the last
		set listFile [file split $filename]
		set listCount [llength $listFile]
		set listIndex [expr $listCount - 1]

		set pictureFile [lindex $listFile $listIndex]

		# If the pictureFile already exists within the
		# working directory we do not copy it again
		if { [file exists $pictureFile] == 0 } {
			# Copy the image to the current directory
			if {[catch {file copy -force "$filename" $pictureFile} sError]}
				 {
				tk_messageBox -message "File Copy Error $filename to 
				$pictureFile"		
			}
		}
		# Update the dictionary entry
		dict set addressInfo $currentRecord PHOTO $pictureFile
		# Update the image onscreen
		image create photo newPicture -file $pictureFile
		.main.picture configure -image newPicture
	}
}
#############################################
# END OF PROCEDURES
#############################################
# Create the dictionary from the file on disk
# if it exists and contains entries
if { [file exists $addressFile]} {
	# If the file exists check that it has contents
	# Since we are managing the file through the application we can 
assume
	# for the sake of our application that it is in the correct format
		if { [file size $addressFile] > 0 } {
			set fp [open $addressFile r+]
			gets $fp data
			while {$data >0} {
				set data2 [split $data ","]
				set recno [lindex $data2 0]
				dict set addressInfo $recno ID [lindex $data2 0]
				dict set addressInfo $recno FNAME [lindex $data2 1]
				dict set addressInfo $recno LNAME [lindex $data2 2]
				dict set addressInfo $recno ADDRESS [lindex $data2 3]
				dict set addressInfo $recno CITY [lindex $data2 4]
				dict set addressInfo $recno STATE [lindex $data2 5]
				dict set addressInfo $recno ZIP [lindex $data2 6]
				dict set addressInfo $recno PHONE [lindex $data2 7]
				dict set addressInfo $recno PHOTO [lindex $data2 8]
				# Open the file
				set pictureFile [dict get $addressInfo $recno PHOTO]
				# Read the data using the gets
		gets $fp data
			}
			close $fp
			set recordCount [dict size $addressInfo]
			set currentRecord 1
			# Load the first record
			loadRecord
			} else {
			 set myTitle "Missing Records"
			 set myMessage "No records exist, please add an entry and click
			  save"
  			 tk_messageBox -message $myMessage 
			 -title $myTitle 
			 -type ok 
			 -icon warning

			 set currentRecord 0
			 set recordCount 0
			 set pictureFile ""
			}
		} else {
			set myTitle "Missing configuration file"
			set myMessage "No address file exists, please add an entry and click 
			  save."
			tk_messageBox -message $myMessage 
			  -title myTitle 
			  -icon warning
		
			  set currentRecord 0
			  set recordCount 0
			  set pictureFile " "
		}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.181.36