Home > Blockchain >  Python / tkinter: Binding right button click in an array of widgets
Python / tkinter: Binding right button click in an array of widgets

Time:09-26

enter code hereI am rendering an array of buttons onto the screen and want to implement a right-click function. I have left click working with the default "command=" option on the widget, but for some reason, I can't seem to get the button bind to kick in. My code looks like this:

for key, value in sorted_widget_properties:
    if key not in self._filter_list:
        continue
    colour = value[appearance_mode_index]
    if row > 18:
        offset = 4
        row = 1

    # Light mode colours
    if row == 1:
        pad_y = (10, 0)
    else:
        pad_y = 5
    lbl_property = ctk.CTkLabel(master=widget_frame, text=' '   key)
    lbl_property.grid(row=row, column=1   offset, sticky='w', pady=pad_y)
    btn_property = ctk.CTkButton(master=widget_frame,
                                 border_width=1,
                                 fg_color=colour,
                                 width=button_width,
                                 height=button_height,
                                 text='',
                                 command=lambda widget_property=key: self.colour_picker(widget_property),
                                 corner_radius=3)
    btn_property.grid(row=row, column=0   offset, padx=5, pady=pad_y)
    self.widgets[key] = {"widget": btn_property, "button": btn_property, "colour": colour,
                         'label': lbl_property}
    # Set a binding so that we can paste a colour, previously copied into our clipboard
    self.widgets[key]['widget'].bind("<Button-3>",
                                     lambda widget_property=key: self._paste_colour(widget_property))
    row  = 1

I have a print statement in the _paste_colour class method, and it appears that the function is never called and nothing is ever printed:

def _paste_colour(self, widget_property):
    print('PASTE COLOUR!"')
    new_colour = pyperclip.paste()
    if len(new_colour) != 7:
        self._status_bar.set_status_text(status_text='Attempt to paste a bad colour code - ignored.')
    self._set_widget_colour(widget_property=widget_property, new_colour=new_colour)
    self._status_bar.set_status_text(
        status_text=f'Colour {new_colour} assigned to widget property {widget_property}.')

Any suggestions appreciated.

Thanks,

Clive

CodePudding user response:

Next time please provide a minimal reproducible example. You have a lot of variables that are not defined in the code you show and the tkinter class is not provided either. Also we do not know if you get any error messages. This makes it difficult to troubleshoot. It might be that you are just missing an event parameter, but not sure if I get your issue correctly.

import tkinter as tk

root = tk.Tk()
root.geometry("200x200")
widget_frame = tk.Frame(root).grid(row=1, column=1)


def right_click(x):
    print('right clicked')
    print(x)

def left_click():
    print('left clicked')


lbl_property = tk.Label(master=widget_frame, text='Label')
lbl_property.grid(row=0, column=0, sticky='w')
btn_property = tk.Button(master=widget_frame,
                             text='button',
                             command=left_click
                             )
btn_property.grid(row=0, column=1, padx=5, pady=5)
param='some parameter'
btn_property.bind("<Button-3>", lambda event, x=param: right_click(x))

root.mainloop()

CodePudding user response:

OK, apologies, I really should have done a bit more prep.

Anyway, taking the above example and replacing with a customtkinter widget. I have reproduced the problem:

import tkinter as tk
import customtkinter as ctk

root = tk.Tk()
root.geometry("200x200")
widget_frame = tk.Frame(root).grid(row=1, column=1)


def right_click(x):
    print('right clicked')
    print(x)

def left_click():
    print('left clicked')


lbl_property = tk.Label(master=widget_frame, text='Label')
lbl_property.grid(row=0, column=0, sticky='w')
btn_property = ctk.CTkButton(master=widget_frame,
                             text='button',
                             command=left_click
                             )
btn_property.grid(row=0, column=1, padx=5, pady=5)
param='some parameter'
btn_property.bind("<Button-3>", lambda event, x=param: right_click(x))

root.mainloop()

Running the above, masks out the right click binding. No errors, just doesn't work.

I'll raise the issue on GitHub on the customtkinter forum.

  • Related