Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

A listbox with a checkboxes: what is my best bet?

2,853 views
Skip to first unread message

Georgios Petasis

unread,
Apr 5, 2011, 7:28:59 AM4/5/11
to
Hi all,

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

Arjen Markus

unread,
Apr 5, 2011, 7:38:41 AM4/5/11
to

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

eugene

unread,
Apr 5, 2011, 7:40:13 AM4/5/11
to
I'd suggest to have a look at Hugelist (http://wiki.tcl.tk/6784). Screenshots clearly show checkboxes in a list and the overall look isn't so bad, I'd say "native enough" :) However, I've never used it...

Arjen Markus

unread,
Apr 5, 2011, 7:40:36 AM4/5/11
to

Yes, via the tags: you can define bindings for them

Regards,

Arjen

MSEdit

unread,
Apr 5, 2011, 8:28:02 AM4/5/11
to

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

Georgios Petasis

unread,
Apr 5, 2011, 10:18:41 AM4/5/11
to

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

WJG

unread,
Apr 5, 2011, 12:05:12 PM4/5/11
to

Ken Jones, Avia Training

unread,
Apr 5, 2011, 12:13:02 PM4/5/11
to
Perhaps you could use a canvas as a manager widget for a listbox or
treeview plus a set of checkboxes. The listbox/treeview bbox widget
commands could give you relative positioning of the items it contains
so that you could calculate checkbox positions.

- Ken

Georgios Petasis

unread,
Apr 5, 2011, 12:58:27 PM4/5/11
to

Yes, I know. But its not Tk, and also GPL... :-)

George

Georgios Petasis

unread,
Apr 5, 2011, 1:23:39 PM4/5/11
to
I have played a little more with treeview, and there is a partial
solution (native indicators under windows, images for the rest). Here it
is (although the bindings need more work):

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

0 new messages