Reputation: 161
I am making a custom button using the tk.Label and my own class so i can import use this in a separate module of a project i don't know how i can replicate the command=
function of the button object, is this a implementation of the callback function or if not where should i look for information on how to acomplish this
import tkinter as tk
class Main(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.geometry(self, "800x400")
tk.Tk.config(self, bg="black")
container = tk.Frame(self)
container.config(bg="black")
container.pack(side="top", fill="both", expand="true", pady=30)
this = Nav(container, text="Button 1")
this.bind("<Button>", lambda event: print("HELLO"))
this.pack()
Nav(container, text="Button 2")
class Nav(tk.Label):
def __init__(self, *args, **kwargs):
btn = tk.Label.__init__(self, *args, **kwargs, bg="green")
def on_enter(event, ref):
ref.config(text="enter", bg="#990000")
def on_leave(event, ref):
ref.config(text="leave", bg="black")
def left_click(event, ref):
ref.config(text="left click")
return True;
def release(event, ref):
ref.config(text="release")
app = Main()
app.mainloop()
Upvotes: 1
Views: 93
Reputation: 15523
Question: how i can implement the
command=
named argument of my ownButton
object.
To get he same usage as command=
and the callback like def callback()
, you have to bind to self.on_left_click
which calls the callback
.
Reference:
Use the
bind
method of theLabel
widget to bind a callback function to an event called"<Button-1>"
.
class Nav(tk.Label):
def __init__(self, parent, **kwargs):
self.command = kwargs.pop('command', None)
# Defaults
kwargs['bg'] = kwargs.get('bg', "green")
kwargs['fg'] = kwargs.get('fg', "white")
super().__init__(parent, **kwargs)
self.bind("<Button-1>", self.on_left_click)
def on_left_click(self, event):
self.command()
Usage:
nav_button = Nav(container, text="Button 1", command=lambda: print("HELLO"))
nav_button .pack()
Upvotes: 1
Reputation: 386020
You need to do four things:
command
parameter, like you do with a Button
,Nav
to call an internal functionFor example, start by adding a command to Main
, and passing that command to Nav
just like you would do with a Button
:
class Main(tk.Tk):
def __init__(self, *args, **kwargs):
...
this = Nav(container, text="Button 1", command=self.do_something)
...
def do_something(self):
print("do_something was called")
Next, define Nav
to accept this parameter.
Note: you're mistakingly using both inheritance and composition (inheriting from Label
and also creating a second Label
) which is unnecessary, so I'm going to remove the second label in the following example.
Since a Label
doesn't support the command
keyword arg, we need to pull that out of kwargs
and save it to a variable before passing the remaining arguments to the __init__
of Label
,
class Nav(tk.Label):
def __init__(self, *args, **kwargs):
self.command = kwargs.pop("command", None)
super().__init__(*args, **kwargs, bg="green")
Your original code has a call to bind
in Main
, but if you're trying to mimic a widget then the bindings need to be inside the widget. With that, this new widget will work just like a button, by specifying a command
rather than bindings.
This is how you would define the <Enter>
, <Leave>
, <ButtonPress>
and <ButtonRelease>
events. I've renamed the functions from your original code to be more consistent with each other.
class Nav(tk.Label):
def __init__(self, *args, **kwargs):
...
self.bind("<Enter>", self.on_enter)
self.bind("<Leave>", self.on_leave)
self.bind("<ButtonPress>", self.on_press)
self.bind("<ButtonRelease>", self.on_release)
And finally, you need to define these methods. Here's the one you're specifically asking about which implements the command
functionality:
class Nav(tk.label):
...
def on_release(self, event):
if self.command is not None:
self.command()
Here are the other methods, replacing ref
with self
, and putting the arguments in the correct order:
def on_enter(self, event):
self.config(text="enter", bg="#990000")
def on_leave(self, event):
self.config(text="leave", bg="black")
def left_click(self, event):
self.config(text="left click")
Upvotes: 1