I want two buttons to show up when I press my rectangle (function door1), each one of them will give different true value to my global variable CHANGED.
The problem is that I'm having trouble with the aligning. The buttons always show up in an additional part to my current window, and I want them to show up on top of my current window
from tkinter import Tk, Canvas, Button
CHANGED = False
def options():
global window
button1 = Button(window, text='Click to change door')
button1.bind("<Button-1>", change)
button1.pack(side='top')
button2 = Button(window, text='Click to keep door')
button2.bind("<Button-1>", keep)
button2.pack(side='top')
def change(*args):
global CHANGED
CHANGED = True
def keep(*args):
global CHANGED
CHANGED = False
def door1(*args):
options()
window = Tk()
canvas = Canvas(window, width=600, height=500)
square1 = canvas.create_rectangle(50, 500, 150, 200, fill="blue", tags="open_door_1")
canvas.tag_bind("open_door_1", "<Button-1>", door1)
canvas.pack()
window.mainloop()
How can I change it?
You can use grid to achieve that, by defining the row to place your widgets :
from tkinter import Tk, Canvas, Button
CHANGED = False
def options():
button1 = Button(window, text='Click to change door')
button1.bind("<Button-1>", change)
button1.grid(row=0, sticky='w')
button2 = Button(window, text='Click to keep door')
button2.bind("<Button-1>", keep)
button2.grid(row=1, sticky='w')
def change(*args):
global CHANGED
CHANGED = True
def keep(*args):
global CHANGED
CHANGED = False
def door1(*args):
options()
window = Tk()
canvas = Canvas(window, width=600, height=500)
square1 = canvas.create_rectangle(50, 500, 150, 200, fill="blue", tags="open_door_1")
canvas.tag_bind("open_door_1", "<Button-1>", door1)
canvas.grid(row=2)
window.mainloop()
EDIT:
A solution to keep the window from resizing when the widgets appear, you can use the rowconfigure method like below and specify a geometry :
Also, another point to fix : you should be careful about the creation of the buttons, each click on the canvas creates 2 more widgets (visible or not depending on the layout).
The functional pattern may not be the best to handle this, you need to define the buttons as global variables and only create them if they are not already displayed :
from tkinter import Tk, Canvas, Button
CHANGED = False
button1 = None
button2 = None
def options():
global button1, button2
button1 = Button(window, text='Click to change door')
button1.bind("<Button-1>", change)
button1.grid(row=0, sticky='w')
button2 = Button(window, text='Click to keep door')
button2.bind("<Button-1>", keep)
button2.grid(row=1, sticky='w')
def change(*args):
global CHANGED
CHANGED = True
def keep(*args):
global CHANGED
CHANGED = False
def door1(*args):
if button1 is None and button2 is None:
options()
window = Tk()
window.geometry("600x600")
window.rowconfigure(2,weight=1)
canvas = Canvas(window, width=600, height=500)
square1 = canvas.create_rectangle(50, 500, 150, 200, fill="blue", tags="open_door_1")
canvas.tag_bind("open_door_1", "<Button-1>", door1)
canvas.grid(row=2,sticky='s')
window.mainloop()
Related
import tkinter as tk
from tkinter import *
HEIGHT = 600
WIDTH = 600
root = tk.Tk()
def button_event1():
import ThreePlayers
print(ThreePlayers)
def button_event2():
import TwoPlayersGame
print(TwoPlayersGame)
def button_event3():
print("")
def button_event4():
print("")
def button_event5():
quit()
root = Tk()
root.title('Connect 4 Game')
canvas = tk.Canvas(root, height=HEIGHT, width=WIDTH)
canvas.pack()
L = Label(root, text="Welcome to 3P Connect 4!!!",font=("Ariel",20,"bold", "underline"))
L.config(anchor=CENTER)
L.pack()
button = tk.Button(root, text="3 Player Game", command=button_event1)
button.pack()
button = tk.Button(root, text="2 Player Game", command=button_event2)
button.pack()
button = tk.Button(root, text="1 Player Game", command=button_event3)
button.pack()
button = tk.Button(root, text="Options", command=button_event4)
button.pack()
button = tk.Button(root, text="QUIT", command=button_event5)
button.pack()
root.mainloop()
Above is my Code for a Tkinter GUI but I want the have the label at the center of the root/window how do I do that? Currently its sitting on top of the buttons everything else is fine the button events and such works
In my opinion, you should have used place or grid instead of pack. Because pack only gives few alignment options.
otherwise, maybe divide the main window into two frames then pack the label at the top of the lower frame
frame = Frame(root)
frame.pack()
bottomframe = Frame(root)
bottomframe.pack( side = BOTTOM )
L = Label(root, text="Welcome to 3P Connect 4!!!",font=("Ariel",20,"bold", "underline"))
L.pack(side = TOP)
I wish this helps. but you should use grid for better alignment or place.
You can use the following commands to place the label in the center
L = Label(root, text="Welcome to 3P Connect 4!!!",font=("Ariel",20,"bold", "underline"))
# L.config(anchor=CENTER)
# L.pack()
L.place(x=HEIGHT/2, y=WIDTH/2, anchor="center")
Similarly, you can also use button.place(x=100, y=25) for buttons
REF: Tkinter: Center label in frame of fixed size?
I have made a calculator using tkinter. In that, I wanted to change the color of the buttons when I hover over it. I did change the color of some buttons, but I couldn't change the color of the digits buttons when I hover it.
self.digits = {
7:(1,1), 8:(1,2), 9:(1,3),
4:(2,1), 5:(2,2), 6:(2,3),
1:(3,1), 2:(3,2), 3:(3,3),
0:(4,2), ".":(4,1),
}
that was the code i used to input the digits.
def create_digit_buttons(self):
for digit,grid_value in self.digits.items():
Button = tk.Button(self.buttons_frame, text=str(digit), bg="#fff", fg="#25265E", font=("Arial", 24, "bold"), borderwidth=0,
command=lambda x=digit: self.add_to_expressions(x))
Button.grid(row=grid_value[0], column=grid_value[1], sticky=tk.NSEW)
And above code is the one i used for the digit buttons.
def changedgt_on_hovering(event):
global create_digit_buttons
Button['bg']='#F0F0F0'
def returndgt_to_normalstate(event):
global create_digit_buttons
Button['bg']='#fff'
Button.bind("<Enter>", changedgt_on_hovering)
Button.bind("<Leave>",returndgt_to_normalstate)
That was the code i used to change the color of the digits buttons when hovering over them.
there's no any error msgs; only decimal point button changes the color when hovering through it, since i added the decimal point(".") to the self.digits part.
below is the full code upto the necessary part...pls help me(I'm a newbie)
from tkinter import *
import tkinter as tk
LABEL_COLOR = "#25265E"
DEFAULT_FONT_STYLE = ("Arial", 20,"bold")
OFF_WHITE = "#F8FAFF"
class Calculator:
def __init__(self):
self.window = tk.Tk()
self.window.geometry("375x660")
self.window.resizable(height=True, width= True)
self.window.title("Calculator")
self.total_expression = ""
self.current_expression = ""
self.display_frame = self.create_display_frame()
self.total_label, self.label =self.create_display_labels()
self.digits = {
7:(1,1), 8:(1,2), 9:(1,3),
4:(2,1), 5:(2,2), 6:(2,3),
1:(3,1), 2:(3,2), 3:(3,3),
0:(4,2), ".":(4,1),
}
self.operations = {"/": "\u00F7", "*": "\u00D7","-": "-", "+": "+"}
self.buttons_frame = self.create_buttons_frame()
self.buttons_frame.rowconfigure(0, weight=1)
for x in range(1,5):
self.buttons_frame.rowconfigure(x, weight=1)
self.buttons_frame.columnconfigure(x, weight=1)
self.create_digit_buttons()
self.create_operator_buttons()
self.create_special_buttons()
self.bind_keys()
def bind_keys(self):
self.window.bind("<Return>", lambda event: self.evaluate())
self.window.bind("<BackSpace>", lambda event: self.delete())
for key in self.digits:
self.window.bind(str(key), lambda event, digits = key: self.add_to_expressions(digits))
for key in self.operations:
self.window.bind(key, lambda event, operator = key: self.append_operator(operator))
def create_special_buttons(self):
self.create_clear_button()
self.create_equals_button()
self.create_delete_button()
self.create_square_button()
self.create_sqrt_button()
def create_display_labels(self):
total_label=tk.Label(self.display_frame, text= self.total_expression, anchor=tk.E, bg="#f5f5f5", fg="#25265E", padx=24, font=
("Arial", 24))
total_label.pack(expand=True, fill="both")
label=tk.Label(self.display_frame, text= self.current_expression, anchor=tk.E, bg="#f5f5f5", fg="#25265E", padx=24, font=
("Arial", 40, "bold"))
label.pack(expand=True, fill="both")
return total_label,label
def create_display_frame(self):
Frame = tk.Frame(self.window, height=221, bg="#f5f5f5")
Frame.pack(expand=True, fill="both")
return Frame
def add_to_expressions(self, value):
self.current_expression += str(value)
self.update_label()
def create_digit_buttons(self):
for digit,grid_value in self.digits.items():
Button = tk.Button(self.buttons_frame, text=str(digit), bg="#fff", fg="#25265E", font=("Arial", 24, "bold"), borderwidth=0,
command=lambda x=digit: self.add_to_expressions(x))
Button.grid(row=grid_value[0], column=grid_value[1], sticky=tk.NSEW)
def changedgt_on_hovering(event):
global create_digit_buttons
Button['bg']='#F0F0F0'
def returndgt_to_normalstate(event):
global create_digit_buttons
Button['bg']='#fff'
Button.bind("<Enter>", changedgt_on_hovering)
Button.bind("<Leave>",returndgt_to_normalstate)
To change the color of a button when the user hovers over it, simply define the activebackground option as the color you want it to be. Here is a simple example:
import tkinter
window = tkinter.Tk()
button = tkinter.Button(window, activebackground="red")
button.pack()
window.mainloop()
This turns the button red when the user hovers over it, and returns it to its original color when the user stops hovering over it.
As well as using words to specify the colors (like yellow, red, green, etc.), you can also use hexadecimal colors as well (like #ffff00, #ff0000, #0000ff, etc.).
You can modify create_digit_buttons() as below:
def create_digit_buttons(self):
def changedgt_on_hovering(event):
# use event.widget instead of hard-coded Button
event.widget['bg']='#F0F0F0'
def returndgt_to_normalstate(event):
# use event.widget instead of hard-coded Button
event.widget['bg']='#fff'
for digit,grid_value in self.digits.items():
Button = tk.Button(self.buttons_frame, text=str(digit), bg="#fff", fg="#25265E", font=("Arial", 24, "bold"), borderwidth=0,
command=lambda x=digit: self.add_to_expressions(x))
Button.grid(row=grid_value[0], column=grid_value[1], sticky=tk.NSEW)
# moved the binding code inside for loop
Button.bind("<Enter>", changedgt_on_hovering)
Button.bind("<Leave>", returndgt_to_normalstate)
When I click on button 2 after pressing on button 1 it does not work.
I am making an auto clicker for fun, as a side project.
import tkinter as tk
from pynput.mouse import Button, Controller
import time
Height = 700
Width = 800
mouse = Controller()
flag = True
def click_function():
while flag == True:
time.sleep(.001)
mouse.click(Button.left, 1)
def endclick_function():
flag = False
root = tk.Tk()
canvas = tk.Canvas(root, height=Height, width=Width)
canvas.pack()
frame = tk.Frame(root,bg='black')
frame.place(relx=0.1, rely=0.1, relwidth=0.8, relheight=0.5)
button = tk.Button(frame, text="Start" , bg='white', fg='black', font=50, command=click_function)
button.place(relx=0, rely=0, relwidth=0.5, relheight=0.5)
button2 = tk.Button(frame, text="Stop" , bg='white', fg='black', font=50, command=lambda: endclick_function)
button2.place(relx=.5, rely=0, relwidth=0.5, relheight=0.5)
label = tk.Label(frame, text='Time to Sleep:', bg='white', font=50)
label.place(relx=0, rely =0.5, relwidth=0.5, relheight=0.25)
label2 = tk.Label(frame, text='How many times to click:', bg='white', font=50)
label2.place(relx=0, rely =0.75, relwidth=0.5, relheight=0.25)
entry = tk.Entry(frame, bg='white')
entry.place(relx=0.5, rely =0.5, relwidth=0.5, relheight=0.25)
entry2 = tk.Entry(frame,text='Time to Sleep(ms):', bg='white')
entry2.place(relx=0.5, rely =0.75, relwidth=0.5, relheight=0.25)
root.mainloop()
you have to declare flag global if you want to change it
also as Joe Ferndz pointed out, the flag is never set back to True
def click_function():
global flag
flag = True # of course, only if you want to use clicker more than once
while flag == True:
time.sleep(.001)
mouse.click(Button.left, 1)
def endclick_function():
global flag
flag = False
Something I just noticed
in button2, command=lambda:end_f
remove lambda
this is basically saying
def l():
return end_f
button2['command'] = l
and since the command (l) is executed at the click on the button,
it only returns the function, does not execute it
When you click the first button, the flag is set to True. However, when you click on second button, the flag gets set to False. Later when you come back to first button, the flag is False so it never goes into the while loop.
Do you want to try and implement this an alternate way?
def click_function():
while flag == True:
time.sleep(.001)
mouse.click(Button.left, 1)
def endclick_function():
flag = False
self.label_5 = tk.Checkbutton(self.master, text="I agree to the", bg='white', width=14,font=("Arial", 8), command= activator)
self.label_5.place(x=112, y=410)
self.button_2 = tk.Button(text='Proceed', width=20, bg='white', state = tk.DISABLED, bd=1,
highlightbackground='black', font=("Arial", 10)).place(x=208, y = 512)
def activator(button):
if (self.button_2 ['state'] == tk.DISABLED):
self.button_2 ['state'] = tk.NORMAL
else:
self.button_2['state'] = tk.DISABLED
I want to enable the proceed button after I checked the checkbutton but I can't seem to figure it out.
You have to make the following changes to your code:
You have to refer to the function named activator as self.activator when giving it to the Button(button_2) as command.
You have to change the parameter named button of the function named activator to self.
And the most important thing you need to do is move the part of code where you are placing the Button(button_2) and the Checkbutton(label_5), to a new line. Like I have done in the code below. The reason for doing so is that pack, grid and place always return None. And when you do it in the same line where you have created your widgets and assigned them to a variable i.e. button_2 and label_5, the value None gets stored in that widget.
Here's the corrected code:
import tkinter as tk
class Test:
def __init__(self):
self.master = tk.Tk()
self.master.geometry('550x550')
self.label_5 = tk.Checkbutton(self.master, text="I agree to the", bg='white', width=14, font=("Arial", 8),
command=self.activator)
self.label_5.place(x=112, y=410)
self.button_2 = tk.Button(text='Proceed', width=20, bg='white', state=tk.DISABLED, bd=1,
highlightbackground='black', font=("Arial", 10))
self.button_2.place(x=208, y=512)
self.master.mainloop()
def activator(self):
if self.button_2['state'] == tk.DISABLED:
self.button_2['state'] = tk.NORMAL
else:
self.button_2['state'] = tk.DISABLED
if __name__ == '__main__':
Test()
I am a python self learner. I was stuck on some practice.
My idea was to create a pop out GUI with buttons that can change the canvas colour.
from Tkinter import *
import ttk
import tkMessageBox
root = Tk()
root.title("Colour!")
canvasColor = "yellow"
def buttonRed() :
canvas = Canvas(root, bg = "red", height=100, width=100)
canvas.grid(row=0,column=2)
button = ttk.Button(root, text="Red", command = buttonRed)
button.grid(row=2,column=1)
button2 = ttk.Button(root, text ="Green", command = buttonGreen)
button2.grid(row=2,column=2)
button3 = ttk.Button(root, text="Blue", command = buttonBlue)
button3.grid(row=2,column=3)
canvas = Canvas(root, bg = canvasColor, height=200, width=200)
canvas.grid(row=0,column=2)
root.configure(background='white')
root.mainloop()
i haven't put in the green and blue button command yet, but instead of creating a new canvas when the colour button clicked, i just wanted to have the default canvas colour change.
Any help will be much appreciated!
Thanks in advance.
I think this is what you need -
from Tkinter import *
import ttk
import tkMessageBox
root = Tk()
root.title("Colour!")
canvasColor = "yellow"
def buttonRed() :
canvas.config(background="red")
def buttonGreen() :
canvas.config(background="green")
def buttonBlue() :
canvas.config(background="blue")
button = ttk.Button(root, text="Red", command = buttonRed)
button.grid(row=2,column=1)
button2 = ttk.Button(root, text ="Green", command = buttonGreen)
button2.grid(row=2,column=2)
button3 = ttk.Button(root, text="Blue", command = buttonBlue)
button3.grid(row=2,column=3)
canvas = Canvas(root, bg = canvasColor, height=200, width=200)
canvas.grid(row=0,column=2)
#canvas.config(background="black")
root.configure(background='white')
root.mainloop()