-2

I 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}.')
2
  • 1
    Please edit your question to include a minimal reproducible example, preferably one that doesn't rely on customtk, unless customtk is literally causing the problem. Commented Sep 23, 2022 at 14:04
  • You need to bind event on self.widgets[key]['widget'].canvas instead. Commented Sep 23, 2022 at 15:58

2 Answers 2

0

It might be that you are just missing an event parameter.

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()
Sign up to request clarification or add additional context in comments.

1 Comment

OK point taken and I should have known better. Based on your example. It appears to be a problem with customtkinter.
0

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.

1 Comment

This did indeed turn out to be a CustomTkinter issue. The issue is now fixed in CustomTkinter version 5.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.