Sarnold: Here is a mega-widget which works together with the Object-oriented SQLite wrapper.
package require Tk
package require tableview_sql
package provide tableview 0.1
namespace eval tableview {
class create tableview {
constructor {hullname sql tbl} {
my variable hull
set hull $hullname
my variable table
set table [tableview::table create $hullname.table $sql $tbl]
my variable columns
set columns ""
my variable height
my variable start
set height 10
set start 1
toplevel $hull
}
# for debugging purposes
method delegate {args} {
my variable table
$table {*}$args
}
method column {sub args} {
my column_$sub {*}$args
}
method column_add {name args} {
my variable table
my variable columns
set options [$table column info options]
set myoptions {-width -title}
dict set columns $name ""
set sql [list $table column add $name]
foreach {opt val} $args {
if {$opt in $options} {
lappend sql $opt $val
} elseif {$opt in $myoptions} {
dict lappend columns $name $opt $val
} else {
error "unknown option $opt"
}
}
eval $sql
}
method draw {args} {
my variable height
my variable hull
set height [tableview::default $args -height $height]
set title [tableview::default $args -title "SQL data"]
wm title $hull $title
my variable columns
foreach col [dict keys $columns] {
pack [frame $hull.$col] -side left
label $hull.$col.title -text [tableview::default [dict get $columns $col] -title $col]
pack $hull.$col.title -side top
for {set i 0} {$i < $height} {incr i} {
pack [label $hull.$col.row$i -text ""] -side top
}
}
pack [scrollbar $hull.scrolling -command [list [self] yview]] -side left
my redraw
my sync_scrolling
}
method sync_scrolling {} {
my variable start
set len [my delegate length]
if {$len == 0} {return}
if {$start > $len} {
# rows have been removed under the cursor
set start 1
my redraw
my sync_scrolling
return
}
my variable hull
my variable height
$hull.scrolling set [expr {double($start-1)/$len}] [expr {min(1.,double($start+$height-1)/$len)}]
}
method yview {sub args} {
my variable start
set start [my yview_$sub {*}$args]
my sync_scrolling
}
method yview_moveto {fraction} {
my redraw [expr {[my delegate length]*$fraction}]
}
method yview_scroll {number type} {
my yview_scroll_$type $number
}
method yview_scroll_units {n} {
my variable start
my variable height
set len [my delegate length]
if {$len < $height || $start+$n<1} {return [my redraw]}
if {$n > 0} {
if {$start+$n > $len-$height+1} {
return [my redraw [expr {$len-$start-$height+1}]]
}
return [my redraw [expr {$start + $n}]]
}
my redraw [expr {$start+$n}]
}
method yview_scroll_pages {n} {
my variable height
my yview_scroll_units [expr {$n*($height-1)}]
}
method redraw {{mystart 1}} {
my variable start
my variable height
my variable table
my variable columns
my variable hull
set mystart [expr {round($mystart)}]
set names [dict keys $columns]
set end [expr {min($height+$mystart-1,[$table length])}]
puts $mystart,$end
set data [$table get range $mystart $end]
for {set i 0} {$i < [llength $data]} {incr i} {
set row [lindex $data $i]
foreach name $names {
$hull.$name.row$i configure -text [dict get $row $name]
}
}
return $mystart
}
}
}Usage:
sqlite3 db my.db tableview::tableview create tbl .tbl db emp tbl column add emp_name -key yes tbl column add emp_age -type integer tbl draw