I am trying to create a car configurator using tkinter as a gui in my free time.
I have managed to open a tkinter box with images that act as buttons.
What I want to do is for the user to click on a button. I want to check which button has been clicked (i.e if the family car button is clicked, how can I check that it has been clicked).
I have done my research on this website, and all of the solutions I have found have been in javascript or other languages.
Once the button has been clicked, I want a new window to be opened ONLY containing attributes for a family car i.e a family car can have a red exterior colour, but a sports car cannot have a red exterior colour at all.
Here is my code below:
from tkinter import *
import tkinter as tk
def create_window():
window = tk.Toplevel(root)
root = tk.Tk()
familycar = PhotoImage(file = "VW family car.png")
familylabel = Button(root, image=familycar)
familybutton = Button(root, image=familycar, command=create_window)
familybutton.pack()
So how can I check that the family car button has been clicked?
Thanks
Use a Boolean flag.
Define isClicked as False near the beginning of your code, and then set isClicked as True in your create_window() function.
This way, other functions and variables in your code can see whether the button's been clicked (if isClicked).
Not sure what you asked, do you want to disable it or check its status in another routine ?
Or just to count the times it has been clicked,
In order to do that Simple solution would be to add a general variable that will be updated inside the create_window method (general because you want to allow access from other places).
First, you would need to initialize a function in which you want to execute on the button click.
example:
def button_clicked():
print('I got clicked')
Then, when you define the target button, you'll have to set the 'command' argument to the required function(the button_clicked function in this context).
Related
I'm designing a GUI application using Tkinter and for this project, I need buttons for the menu. While looking into the buttons I wasn't blown away by the customization options that come with the buttons, especially when I found out that you can bind click arguments to rectangles.
This allows me to customize the "button" in (almost) limitless ways, but to allow me to put text on the button I need to create a rectangle element and a text element and bind them together using Tkinter's tag_bind property.
One of the design properties of the button that I wanted was active fill when the user moused over the element. Right now I'm just using activefill="" which works, except the text element and the button element will only fill while the mouse is over that element. So, for example, when I mouse over the button the button excluding the text will highlight and vise versa when I mouse over the text.
Below is a simplified (for brevity) version of what I use to generate the buttons;
button = canvas.create_rectangle(button_width, button_height, 10, 10, fill="000", activefill="111", tags="test")
text = canvas.create_text((button_width/2), (button_height/2), activefill="111", tags="test")
canvas.tag_bind("test", "<Button-1>", "foo")
Is there a way to bind the active fill function to a tag rather than a specific element?
Another option is that I completely missed a bunch of information about customizing the buttons in Tkinter, and I would not be apposed to learning about that.
Option 1
I would personally not go for the presented solution. I do not know if you are using the button provided by tk or ttk. But, with the tkinter.tk, you could absolutely change the appearance of the button.
Following, I give you an example that produces a button with the following characteristics:
Blue foreground
Flat appearance
When hovered, the background is green
When pressed, the background is red
The code is as follows:
import tkinter as tk
root = tk.Tk()
# Function hovering
def on_enter(e):
btn['background'] = 'green'
def on_leave(e):
btn['background'] = 'white'
# Create the button
btn = tk.Button(root, background='white', activebackground='red', foreground='blue',relief='flat',text='Test',width=20)
btn.pack()
# Bindings
btn.bind("<Enter>", on_enter)
btn.bind("<Leave>", on_leave)
# Loop
root.mainloop()
Option 2
If even after having tried the tk.Button, you are not glad with the result, I would create a Frame containing a Label (you can do nearly anything with that combination). Then, you could change the background of the frame according to any user action, like:
import tkinter as tk
root = tk.Tk()
# Function hovering
def on_enter(e):
lab['background'] = 'green'
def on_leave(e):
lab['background'] = 'white'
# Click
def on_click(e):
print("hi")
# Create the frame with a label inside
fr = tk.Frame(root)
lab = tk.Label(fr, text="Test", width=20, background="white")
# Packing
fr.pack()
lab.pack()
# Bindings
fr.bind("<Enter>", on_enter)
fr.bind("<Leave>", on_leave)
lab.bind("<Button-1>", on_click)
# Loop
root.mainloop()
You could even create a class with the above combination.
I'm new using tkinter on python and I would like to develop a program that can Drag and Drop a button pressing other one... I will try to explain : I have button 'A' that will create a new button 'B' and I want to Drag the New button to another place
Any help
Thanks
The tkinter.dnd module, as suggested by j_4321 in comments.
Here is some sample code using that library to do what you have said:
from tkinter import *
from tkinter.dnd import Tester as DragWindow, Icon as Dragable
# Make a root window and hide it, since we don't need it.
root = Tk()
root.withdraw()
# Make the actual main window, which can have dragable objects on.
main = DragWindow(root)
def make_btn():
"""Make a new test button."""
# The functional part of the main window is the canvas.
Dragable('B').attach(main.canvas)
# Make a button and bind it to our button creating function.
Button(main.top, text='A', command=make_btn).pack()
# Start the mainloop.
mainloop()
Is there a best practice for making a tkinter button momentarily change color when it is selected (so the user gets a visual feedback that the button was pressed).
I have read it is not a good idea to use time.sleep() in a tkinter GUI.
When my button is pressed, the code happens so fast that even when I have a button.config() command to change color, it doesn't occur without using time.sleep()
Any suggestions?
I think this may be what you want:
Button(background=normal_color, foreground=text_color,
activebackground=pressed_color, activeforeground=pressed_text_color)
This changes the button from normal_color to pressed_color when the button is pressed.
It's actually a simple question with a simple answer but I had to look everywhere too. Finally found this answer by reading http://effbot.org/tkinterbook/button.htm.
You can change the color upon clicking, then use the after method to reset the color back to the original, after some time has passed
import tkinter as tk
def reset_color():
bt['fg'] = 'black'
def clickme():
print('clicked')
bt['fg'] = 'red'
root.after(2000, reset_color) # after 2 seconds
root = tk.Tk()
bt = tk.Button(root, text='will color for a while\nafter clicked', command=clickme)
bt.pack()
root.mainloop()
I have created the following button in a tinter window:
resetall = Button(text = "Clear ALL", command = confirmation)
resetall.pack(side = "left")
This button "Clears" the canvas that the user is drawing on with the Python turtle, but I want this button to be enabled under CERTAIN CONDITIONS, such as if one function is running or not. I have tried this:
if draw.drawing == False:
resetall.config(state = DISABLED)
elif draw.drawing == True:
resetall.config(state = NORMAL)
to enable the button ONLY when the "draw" function is true, otherwise disable it. However, it does not seem to work, as even when the draw function becomes true, it does not get enabled. What am I doing wrong here? Any help is much appreciated! :)
Twas a very simple fix. All I had to do was make resetall a global variable, and then assign resetall.config(state = ACTIVE) to draw.
Make the variable containing a button to be a global variable and then the state of the button can be changed by using button_name.config(state=ACTIVE) or button_name.config(state=DISABLED).
Remember- once the button has been disabled you will not be able to activate it if you have changed the state of the button to disabled inside that same function. You would need another function to activate your previous button once disabled
I'm trying to make a Tkinter menu that is like a taskbar checker.
So if I go to this menu and check a box, a specific button then appears on my window, and then the user can select multiple buttons based on what they want.
The program is just a bunch of buttons that after entering text in my text field, and clicking the button, a web browser launches with a search of the website that the button is linked to.
How can I make a menu like I mentioned above?
Edit:
I've just tried basic menu stuff:
buttonmenu = Menu(menubar, tearoff=0)
buttonmenu.add_command(label="button1", command=turnbuttononoff)
buttonmenu.add_command(label="button2", command=turnbuttononoff)
buttonmenu.add_command(label="button3", command=turnbuttononoff)
buttonmenu.add_command(label="button4", command=turnbuttononoff)
buttonmenu.add_command(label="button5", command=turnbuttononoff)
This just creates a basic menu. And if I could have a function that triggers a button to be turned on or off that would be great.
So essentially just a function to swap a button from being shown to not being shown
def turnbuttononoff():
#togglebutton here
ANSWER:
I made a dictionary of the data of where each button was stored, and then checked to see if the button was active, and if it was, turned it off, and if it was inactive, turn it off.
Making this a command lambda function for each button works.
def Toggle_Button(myButton):
if myButton.winfo_ismapped()==1:
myButton.grid_forget()
else:
myButton.grid(row=gridData[myButton][0],column=gridData[myButton][1])
gridData = {}
gridData[button] = [row,col]
def Toggle_Button(myButton):
if myButton.winfo_ismapped()==1:
myButton.grid_forget()
else:
myButton.grid(row=gridData[myButton][0],column=gridData[myButton][1])
If you already have buttons on a grid, use button.grid_info to find what you need, it returns a dictionary.