How to move the checkbox to the left side of the column?

143 Views Asked by At

I have been working on a small program where I needed to add a column of checkboxes on the right side of the window. Although I managed to do so by referencing the code at
How to add checkbuttons to every row of a table read from csv in tkinter?, I was wondering if it is possible to justify the images of checkboxes to the left side of the column just like other texts.

Here is what I have done so far. What I have done so far.

Here is the final result that I want to achieve. The final result.

Here is my code.

import tkinter as tk
from tkinter import ttk

root = tk.Tk()


class CbTreeview(ttk.Treeview):
    def __init__(self, master=None, **kw):
        kw.setdefault('style', 'cb.Treeview')
        kw.setdefault('show', 'headings')  # hide column #0
        ttk.Treeview.__init__(self, master, **kw)
        # create checheckbox images
        self._im_checked = tk.PhotoImage('checked',
                                         data=b'GIF89a\x0e\x00\x0e\x00\xf0\x00\x00\x00\x00\x00\x00\x00\x00!\xf9\x04\x01\x00\x00\x00\x00,\x00\x00\x00\x00\x0e\x00\x0e\x00\x00\x02#\x04\x82\xa9v\xc8\xef\xdc\x83k\x9ap\xe5\xc4\x99S\x96l^\x83qZ\xd7\x8d$\xa8\xae\x99\x15Zl#\xd3\xa9"\x15\x00;',
                                         master=self)
        self._im_unchecked = tk.PhotoImage('unchecked',
                                           data=b'GIF89a\x0e\x00\x0e\x00\xf0\x00\x00\x00\x00\x00\x00\x00\x00!\xf9\x04\x01\x00\x00\x00\x00,\x00\x00\x00\x00\x0e\x00\x0e\x00\x00\x02\x1e\x04\x82\xa9v\xc1\xdf"|i\xc2j\x19\xce\x06q\xed|\xd2\xe7\x89%yZ^J\x85\x8d\xb2\x00\x05\x00;',
                                           master=self)
        style = ttk.Style(self)
        style.configure("cb.Treeview.Heading", font=(None, 13))
        # put image on the right
        style.layout('cb.Treeview.Row',
                     [('Treeitem.row', {'sticky': 'nswe'}),
                      ('Treeitem.image', {'side': 'right', 'sticky': 'e'})])

        # use tags to set the checkbox state
        self.tag_configure('checked', image='checked')
        self.tag_configure('unchecked', image='unchecked')

    def tag_add(self, item, tags):
        new_tags = tuple(self.item(item, 'tags')) + tuple(tags)
        self.item(item, tags=new_tags)

    def tag_remove(self, item, tag):
        tags = list(self.item(item, 'tags'))
        tags.remove(tag)
        self.item(item, tags=tags)

    def insert(self, parent, index, iid=None, **kw):
        item = ttk.Treeview.insert(self, parent, index, iid, **kw)
        self.tag_add(item, (item, 'unchecked'))
        self.tag_bind(item, '<ButtonRelease-1>',
                      lambda event: self._on_click(event, item))

    def _on_click(self, event, item):
        """Handle click on items."""
        if self.identify_row(event.y) == item:
            if self.identify_column(event.x) == '#3': # click in 'Served' column
                # toggle checkbox image
                if self.tag_has('checked', item):
                    self.tag_remove(item, 'checked')
                    self.tag_add(item, ('unchecked',))
                else:
                    self.tag_remove(item, 'unchecked')
                    self.tag_add(item, ('checked',))



tree = CbTreeview(root, columns=("Character Name", "Leveled up to 90", "Is Lv 90"),
                  height=20, selectmode="extended")

tree.heading('Character Name', text="Character Name", anchor='w')
tree.heading('Leveled up to 90', text="Is Lv 90", anchor='w')
tree.heading('Is Lv 90', text="Is Lv 90", anchor='w')
tree.column('#1', stretch='no', minwidth=0, width=150)
tree.column('#2', stretch='no', minwidth=0, width=0)
tree.column('#3', stretch='no', minwidth=0, width=120)


tree.pack(fill='both')

tree.insert('', 'end', values=('Amber', True, ''))
tree.insert('', 'end', values=('Jean', False, ''))
tree.insert('', 'end', values=('Lisa', True, ''))
tree.insert('', 'end', values=('Keqing', True, ''))
tree.insert('', 'end', values=('Ganyu', True, ''))
# for i in range(5):
#     tree.insert('', 'end', values=(i, i, i))
root.mainloop()
1

There are 1 best solutions below

0
toyota Supra On

I was wondering if it is possible to justify the images of checkboxes to the left side of the column just like other texts.

To fix problem. You have four typo errors.

  • In line 63, keyword text="Is Lv 90" is not identical heading
  • In line 65-67, tree.column is not is not identical as heading
  • In line 66, keyword width=0 cannot be set to zero. Setting to zero, the column is not showing and cannot move column 3.

Change in line 63- 67:

tree.heading('Leveled up to 90', text="Is Lv 90", anchor='w')
tree.heading('Is Lv 90', text="Is Lv 90", anchor='w')
tree.column('#1', stretch='no', minwidth=0, width=150)
tree.column('#2', stretch='no', minwidth=0, width=0)
tree.column('#3', stretch='no', minwidth=0, width=120)

to:

tree.heading('Leveled up to 90', text="Leveled up to 90", anchor='w')
tree.heading('Is Lv 90', text="Is Lv 90", anchor='w')
tree.column('Character Name', stretch='no', minwidth=0, width=150)
tree.column('Leveled up to 90', stretch='no', minwidth=0, width=150)
tree.column('Is Lv 90', stretch='no', minwidth=0, width=120)

Screenshot, You can see column 1 and column 3:

enter image description here