Python Forum
[Tkinter] Scrollable Treeview: change behavior of Prior/Next keys?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Scrollable Treeview: change behavior of Prior/Next keys?
#1
Question 
My program has two components I want to control via the keyboard, an image that moves up/down/left/right within a canvas, and a scrollable Treeview that controls the coloring of the image.
Treeview and movable image
Currently the Left, Right, Next, and Prior keys control the image placement, and the Up and Down keys control the selected coloring in the Treeview. It works.

But what I really want is to swap the behavior of the Up key with the Prior key, and the Down key with the Next key, so I can use the arrow keys to control the image placement, and Prior/Next to do what Up/Down would normally do in the Treeview. The problem is getting the Prior and Next keys to do what the Up and Down keys would normally do in the Treeview. Is this even possible? Here's what my current code looks like:
class PartTree(ttk.Treeview):
    """ Using code based on discussion with boughtonp at
            https://www.linuxquestions.org/questions/showthread.php?p=6235877#post6235877
            to not change selection when using <Up> and <Down>
    """

    def __init__(self, parent=None):
        super().__init__(parent, columns=('Part1', 'Part2'))

        # code omitted 
        
        # Force Treeview not to respond to PgDn/PgUp
        self.unbind_class('Treeview', '<KeyPress-Next>')
        self.unbind_class('Treeview', '<KeyPress-Prior>')
        self.unbind_class('Treeview', '<KeyPress-Next>')
        self.unbind_class('Treeview', '<KeyPress-Prior>')

        # grab focus when Up/Dn released (after highlight bar has moved)
        self.bind_class('Treeview', '<KeyRelease-Up>', self.set_selection)
        self.bind_class('Treeview', '<KeyRelease-Down>', self.set_selection)

    # ----------------------------------
    def set_selection(self,event):
        """ Set focus to currently highlighted partitioning """

        self.current_selection = event.widget.selection();
        self.focus(self.current_selection)
Reply
#2
If you want to embed a dropbox image use the image button and replace ?dl=0 with ?raw=1


[Image: Screenshot%20at%202021-04-09%2011-56-06.png?raw=1]
Reply
#3
Figured it out. Unbinding the ability of a PartTree's to respond to Up/Down and Prior/Next, and handling the Prior and Next keys via ConvexHull's on_tree_select method looks like it does what I want.
class PartTree(ttk.Treeview):
    """ Using code based on discussion with boughtonp at
            https://www.linuxquestions.org/questions/showthread.php?p=6235877#post6235877
            to not change selection when using <Up> and <Down>
    """

    def __init__(self, parent=None):

        # Force Treeview not to respond to Up/Down
        self.unbind_class('Treeview', '<KeyPress-Down>')
        self.unbind_class('Treeview', '<KeyPress-Up>')
        self.unbind_class('Treeview', '<KeyPress-Down>')
        self.unbind_class('Treeview', '<KeyPress-Up>')

        # Force Treeview not to respond normally to PgDn/PgUp
        self.unbind_class('Treeview', '<KeyPress-Next>')
        self.unbind_class('Treeview', '<KeyPress-Prior>')
        self.unbind_class('Treeview', '<KeyRelease-Next>')
        self.unbind_class('Treeview', '<KeyRelease-Prior>')

    # ----------------------------------
    def scroll_the_tree(self, key):
        """ Finally got this working! Tree will scroll using the
            PgUp ('Prior') and PgDown ('Next') keys.
        """
        delta = -1 if key=='Prior' else 1

        knt = len(self.get_children())

        int_cs = int(self.selected_row)
        int_cs += delta
        int_cs = max(0, int_cs)
        int_cs = min(int_cs, knt-1)

        self.selection_set(int_cs)
        self.focus(int_cs)
        self.see(int_cs)

        ...

 # ======================================================================
class ConvexHull(tk.Tk):

    def initUI(self):

        # create the partitionings tree and its scrollbar
        self.part_tree = PartTree(l_canvas)
        self.tree_scroll = ttk.Scrollbar(l_canvas, orient="vertical", command=self.part_tree.yview)
        self.part_tree.configure(yscrollcommand=self.tree_scroll.set)

        # when new partitioning selected, do what's necessary
        self.part_tree.bind('<ButtonRelease-1>',  self.on_tree_select)
        self.part_tree.bind('<KeyRelease-Prior>', self.on_tree_select)
        self.part_tree.bind('<KeyRelease-Next>',  self.on_tree_select)

    # ----------------------------------
    def on_tree_select(self, event):

        # do this only on selection by keypress
        key = event.keysym
        if key in {'Prior', 'Next'}:
            self.part_tree.scroll_the_tree(key)

        # do the following regardless of how selection was made
        ...
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [PyQt] PyQt5 drawing on scrollable area HeinKurz 3 1,321 Mar-28-2023, 12:58 PM
Last Post: Axel_Erfurt
  [Tkinter] Scrollable buttons with an add/delete button Clich3 5 3,424 Jun-16-2022, 07:19 PM
Last Post: rob101
Question [Tkinter] Change Treeview column color? water 3 9,591 Mar-04-2022, 11:20 AM
Last Post: Larz60+
  [Tkinter] [split] Is there a way to embed a treeview as a row inside another treeview? CyKlop 5 3,351 Oct-20-2021, 12:14 AM
Last Post: CyKlop
  [Tkinter] How to create scrollable frame mandiatutti 7 4,432 Aug-07-2021, 03:34 PM
Last Post: deanhystad
  Scrollable big image in a window (TKinter) Prospekteur 3 4,472 Sep-14-2020, 03:06 AM
Last Post: Larz60+
  [Tkinter] Fixate graphs on scrollable canvas janema 6 5,424 Apr-12-2019, 03:57 PM
Last Post: Larz60+
  [Tkinter] ListBox not contained or scrollable kellykimble 6 5,175 Apr-05-2018, 11:59 AM
Last Post: Larz60+

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020