I want to create a widget that will allow user to select from a list of
items. And I want selection to be visible with a ckeckbox tick on the
left side. I know that tablelist does that with images, but I am after a
native look (which means something around ttk?).
What is the best listbox that can be modified to do this?
George
With treeview widget you can specify an image per item. With a bit of
programming you can probably get the checkbox effect you want.
Regards,
Arjen
Yes, via the tags: you can define bindings for them
Regards,
Arjen
I use Tablelist and it works very well you just need to define the
images, Mac/Windows only really have one pair each, you could probably
find a way of capturing a pair of checkbox images automatically.
The fact that the checkboxes do not exactly look like the 'native'
ones is not a big problem. Think gmail with its check boxes.
Martyn
I have been playing with the treeview widget, trying to modify its
layout to add a checkbutton indicator.
Fixing the visual part (adding the indicator) was easy:
package require Tk
package require Ttk
foreach target_layout {CheckTreeview CheckTreeview.Item CheckTreeview.Cell
CheckTreeview.Heading CheckTreeview.Row} \
original_layout {Treeview Item Cell Heading Row} {
ttk::style layout $target_layout [ttk::style layout
$original_layout]
ttk::style configure $target_layout {*}[ttk::style configure
$original_layout]
ttk::style map $target_layout {*}[ttk::style map
$original_layout]
puts "$original_layout: [ttk::style map $original_layout]"
}
ttk::style layout CheckTreeview.Item {
Treeitem.padding -sticky nswe -children {
Treeitem.indicator -side left -sticky {}
Checkbutton.indicator -side left -sticky {}
Treeitem.image -side left -sticky {}
Treeitem.focus -side left -sticky {} -children {
Treeitem.text -side left -sticky {}
}
}
}
ttk::treeview .t -columns {A B} -style CheckTreeview
ttk::treeview .t2 -columns {A B}
pack .t -fill both -expand 1
pack .t2 -fill both -expand 1
for {set i 0} {$i < 8} {incr i} {
.t insert {} end -text hello -values {A B}
.t2 insert {} end -text hello -values {A B}
}
But this "alternate" state set on every second item destroys the view :-)
From the sources, I see that this alternate state is "temporarily" set
in DrawItem(), i.e. it is not stored in the item's state variable.
Is there a way to make this optional? I.e. add a configuration option to
the widget for this?
Also, what I miss, is access to the states of items.
Something like itemstate & initemstate.
Do you think that these are good additions to the treeview widget?
Of course I would like the ability to map states to other states, i.e.
be able to modify the Checkbutton.indicator so as alternate state is
never drawn, but I think this is a major change for ttk...
(I know that under windows I can define my own vsapi element that can
have the mapping from states to visual state I want, but this is
platform specific, unfortunately...)
George
https://sites.google.com/site/gnocltclgtk/gnocl-user-documentation/tree-and-list-widgets/gnocl-list
Does all that you want.
Will
- Ken
Yes, I know. But its not Tk, and also GPL... :-)
George
package require Tk
package require Ttk
namespace eval ::checktreeview {
proc createLayout {} {
## Copy the Treeview layouts into a CheckTreeview layout...
foreach t_layout {CheckTreeview CheckTreeview.Item
CheckTreeview.Cell CheckTreeview.Heading
CheckTreeview.Row} \
o_layout {Treeview Item Cell Heading Row} {
ttk::style layout $t_layout [ttk::style layout $o_layout]
ttk::style configure $t_layout {*}[ttk::style configure $o_layout]
ttk::style map $t_layout {*}[ttk::style map $o_layout]
}
## Create a new indicator item, using vsapi under windows, and image
## if vsapi fails...
try {
## To try the image variant, uncomment the following line...
## error help
ttk::style element create CheckTreeview.indicator vsapi BUTTON 3 {
{disabled !selected} 4
{disabled selected} 8
{pressed !selected} 3
{pressed selected} 7
{active !selected} 2
{active selected} 6
!selected 1
selected 5
{} 1
} -margins {0 0 4 0}
} on error {} {
## We failed to create an element with vsapi. Try with images...
image create photo ::checktreeview::CheckTreeview.indicator.checked \
-data \
{R0lGODdhCwALAJEAAH9/f////wAAAP///ywAAAAACwALAAACLISPRvEPAE8oAMUXCYAgJSEiAYRI
QkSCAgTJjgiAoEgSEQGEJIRiA9wdwUcrADs=}
image create photo
::checktreeview::CheckTreeview.indicator.unchecked \
-data \
{R0lGODdhCwALAJEAAH9/f////////////ywAAAAACwALAAACH4SPRvEPADEIYPwDQAwCGP8AEIMA
xj8AxCCA8Y/goxUAOw==}
ttk::style element create CheckTreeview.indicator image {
::checktreeview::CheckTreeview.indicator.unchecked
selected ::checktreeview::CheckTreeview.indicator.checked
} -border {4 0 0 0}
}
## Change the Item layout, and insert an indicator...
ttk::style layout CheckTreeview.Item {
Treeitem.padding -sticky nswe -children {
Treeitem.indicator -side left -sticky {}
CheckTreeview.indicator -side left -sticky {}
Treeitem.image -side left -sticky {}
Treeitem.focus -side left -sticky {} -children {
Treeitem.text -side left -sticky {}
}
}
}
## Copy the bindings from Treeview...
ttk::copyBindings Treeview CheckTreeview
## Modify <1> binding to toggle selection...
bind CheckTreeview <ButtonPress-1> { ::checktreeview::Press %W %x %y }
};# createLayout
proc Press {w x y} {
focus $w
switch -- [$w identify region $x $y] {
nothing { }
heading { heading.press $w $x $y }
separator { resize.press $w $x $y }
tree -
cell {
set item [$w identify item $x $y]
ttk::treeview::SelectOp $w $item toggle
switch -glob -- [$w identify element $x $y] {
*indicator -
*disclosure { ttk::treeview::Toggle $w $item }
}
}
}
};# Press
proc treeview {pathname args} {
ttk::treeview $pathname -style CheckTreeview -class CheckTreeview
{*}$args
};# treeview
createLayout
};# namespace eval ::checktreeview
## Test code:
checktreeview::treeview .t -columns {A B}
ttk::treeview .t2 -columns {A B}
pack .t -fill both -expand 1
pack .t2 -fill both -expand 1
for {set i 0} {$i < 8} {incr i} {
.t insert {} end -text hello -values {A B}
.t2 insert {} end -text hello -values {A B}
}
Works with 8.6.
George