In this frame I have 5 buttons. Each button has nearly all the same settings. My code then looks quite crowded and it takes longer to reproduce.
homeButton = tk.Button(navFrame,command=lambda:self.switch(homeButton,"homeFrame"),image=home,
bg=colour["red"],activebackground=colour["black"],bd=0, cursor="hand2",width=100,height=100)
homeButton.place(x=50,y=150,anchor="center")
taskButton = tk.Button(navFrame,command=lambda:self.switch(taskButton,"taskFrame"),image=tasks,
bg=colour["red"],activebackground=colour["black"],bd=0, cursor="hand2",width=100,height=100)
taskButton.place(x=50,y=250,anchor="center")
monitorButton = tk.Button(navFrame,command=lambda:self.switch(monitorButton,"monitorFrame"),image=proxy,
bg=colour["red"],activebackground=colour["black"],bd=0, cursor="hand2",width=100,height=100)
monitorButton.place(x=50,y=350,anchor="center")
controllerButton = tk.Button(navFrame, command=lambda:self.switch(controllerButton,"controllerFrame"),image=options,
bg=colour["red"], activebackground=colour["black"],bd=0, cursor="hand2",width=100,height=100)
controllerButton.place(x=50,y=450,anchor="center")
settingsButton = tk.Button(navFrame,command=lambda:self.switch(settingsButton,"settingsFrame"),image=settings,
bg=colour["red"],activebackground=colour["black"],bd=0, cursor="hand2",width=100,height=100)
settingsButton.place(x=50,y=550,anchor="center")
Is there a way, like in css/html to set these settings for all buttons in this frame (navFrame
).
I've had a look and not much is said on the topic.
Also Tkinter sucks, if anyone can recommend any better Python GUI tools as it's very limiting not being able to create rounded buttons.
CodePudding user response:
I just create a function that sets up my buttons for me:
def set_up_buttons(button, x_placement, y_placement, navFrame, image):
button.configure(navFrame, image=image,bg=colour["red"], activebackground=colour["black"], bd=0, cursor="hand2",width=100,height=100)
button.place(x = x_placement, y = y_placement, anchor = "center")
homeButton = tk.Button(command=lambda:self.switch(homeButton,"homeFrame"))
set_up_buttons(homeButton, 50, 150, navFrame, home)
# Do the above two lines for every button that you have.
I am sure that there are many more efficient solutions, but this is what I use.
For your other question, I personally use Tkinter but have heard that PyQt is a good choice, but advanced. PySimpleGUI is easy to implement and recommended.
CodePudding user response:
Using the option database
At its core, tkinter uses something called an option database for managing default options to widgets. For an excellent description of how the option database works from a tcl/tk perspective see Options and Tk - A Beginner's Guide. You'll have to do some simple mental translations to convert the code examples to python/tkinter, but it's not that difficult to do.
Setting options happens with the option_add
method, available on any widget. You need to give it an option pattern that describes the option being set along with widget names or classes that will get the option value.
If you want to set the value before creating the frame, you need to specify a widget name. Otherwise, you can wait until the widget has been created and then use the name that was auto-generated.
For your case, I recommend using the name "navFrame" for your widget name. You can then define the options prior to creating the widget. For example:
root.option_add("*navFrame.Label.background", "red")
root.option_add("*navFrame.Label.cursor", "hand2")
root.option_add("*navFrame.Label.width", 100)
root.option_add("*navFrame.Label.height", 100)
You need to make sure your frame has the name navFrame
, which you can do when you create the frame:
navFrame = tk.Frame(root, name="navFrame")
Although I've shown how to set the values in the code, you can also put all of the options in a file and load them all up at once. This is a quick and easy way to support themes, giving each theme its own file of options.
There are many questions and answers on this site that deal with the option database.
Using a custom class
A more pythonic solution is to create a custom class, where you can hard-code any defaults that you want. For example, you might want to create a NavButton
class that looks something like this:
class NavButton(tk.Button):
def __init__(self, parent, **kwargs):
kwargs.setdefault("bg", "red")
kwargs.setdefault("cursor", "hand2")
...
super().__init__(parent, **kwargs)
You would then use NavButton
like a normal button:
homeButton = NavButton(navFrame, text="Home", command=...)
taskButton = NavButton(navFrame, text="Task", command=...)
...