I have been working on my final project, where we are supposed to create a tank game in tkinter. I have done the movement, however i´ve been struggling with the rotation of my tank. Yesterday, I manually calculated all the x and y coordinates for rotation and it works, but for some reason, when i rotate the tank for example to left, back to normal(till here it works) and then to left again the tank just completely messes up. Can´t think of reason why this is happening. Would appreciate some help.
Here is my code :
from tkinter import *
x=0
y=0
poloha="hore"
class Tank:
def __init__(self, delta) -> None:
"""""
x=input("Enter position of tank(x):")
y=input("Enter position of tank(y):")
"""""
self.t1 = plocha.create_rectangle(int(x)+50,int(y)+375,int(x)+100,int(y)+425)
self.t2 = plocha.create_rectangle(int(x)+45,int(y)+370,int(x)+50,int(y)+430)
self.t3 = plocha.create_rectangle(int(x)+100,int(y)+370,int(x)+105,int(y)+430)
self.t4 = plocha.create_rectangle(int(x)+72.5,int(y)+350,int(x)+77.5,int(y)+400)
self.delta = delta
#Movement
def left(event):
plocha.move(event.t1, -event.delta, 0)
plocha.move(event.t2, -event.delta, 0)
plocha.move(event.t3, -event.delta, 0)
plocha.move(event.t4, -event.delta, 0)
def right(event):
plocha.move(event.t1, +event.delta, 0)
plocha.move(event.t2, +event.delta, 0)
plocha.move(event.t3, +event.delta, 0)
plocha.move(event.t4, +event.delta, 0)
def up(event):
x1, y1, x2, y2 = plocha.coords(event.t4)
if y1 - 1 > 0:
plocha.move(event.t1, 0, -event.delta)
plocha.move(event.t2, 0, -event.delta)
plocha.move(event.t3, 0, -event.delta)
plocha.move(event.t4, 0, -event.delta)
else:
pass
def down(event):
x1, y1, x2, y2 = plocha.coords(event.t4)
if y2 + 1 < 500:
plocha.move(event.t1, 0, +event.delta)
plocha.move(event.t2, 0, +event.delta)
plocha.move(event.t3, 0, +event.delta)
plocha.move(event.t4, 0, +event.delta)
else:
pass
def down_turn(event):
global poloha
poloha="dole"
x1, y1, x2, y2 = plocha.coords(event.t4)
plocha.coords(event.t4, x1, y1+55, x2 , y2+55)
plocha.update()
def up_turn(event):
global poloha
if poloha=="vpravo":
x1, y1, x2, y2 = plocha.coords(event.t2)
plocha.coords(event.t2, x1, y1, x2 - 60, y2 + 55)
x1, y1, x2, y2 = plocha.coords(event.t3)
plocha.coords(event.t3, x1+55, y1-55 , x2-5 , y2)
x1, y1, x2, y2 = plocha.coords(event.t4)
plocha.coords(event.t4, x1 - 5, y1 - 50, x2 - 50, y2 - 5)
plocha.update()
if poloha=="vlavo":
x1, y1, x2, y2 = plocha.coords(event.t2)
plocha.coords(event.t2, x1 + 60, y1 - 55, x2 - 5, y2)
x1, y1, x2, y2 = plocha.coords(event.t3)
plocha.coords(event.t3, x1 + 5, y1, x2 - 60, y2 + 55)
x1, y1, x2, y2 = plocha.coords(event.t4)
plocha.coords(event.t4, x1+50, y1 - 50, x2-5, y2 +5)
plocha.update()
if poloha=="dole":
x1, y1, x2, y2 = plocha.coords(event.t4)
plocha.coords(event.t4, x1, y1 - 55, x2, y2 - 55)
plocha.update()
def right_turn(event):
global poloha
up_turn(event)
poloha="vpravo"
x1,y1,x2,y2=plocha.coords(event.t2)
plocha.coords(event.t2,x1,y1,x2+60,y2-55)
x1, y1, x2, y2 = plocha.coords(event.t3)
plocha.coords(event.t3, x1+10, y1+60, x2 -60, y2-5)
x1, y1, x2, y2 = plocha.coords(event.t4)
plocha.coords(event.t4, x1+5,y1+50,x2+50,y2-5)
plocha.update()
def left_turn(event):
global poloha
up_turn(event)
poloha="vlavo"
x1,y1,x2,y2=plocha.coords(event.t2)
plocha.coords(event.t2,x1+60,y1+55,x2-5,y2)
x1, y1, x2, y2 = plocha.coords(event.t3)
plocha.coords(event.t3, x1+5, y1,x2-60, y2-55)
x1,y1,x2,y2=plocha.coords(event.t4)
plocha.coords(event.t4, x1+5,y1+50,x2-50,y2-5)
plocha.update()
master = Tk()
master.title("WOT")
plocha = Canvas(master, width=800, height=500)
global t1,t2,t3,t4 # later delete
tank = Tank(5)
delta = 5
#Movement
plocha.bind("<w>", lambda event: up(tank))
plocha.bind("<a>", lambda event: left(tank))
plocha.bind("<s>", lambda event: down(tank))
plocha.bind("<d>", lambda event: right(tank))
plocha.bind("<Down>", lambda event: down_turn(tank))
plocha.bind("<Up>", lambda event: up_turn(tank))
plocha.bind("<Right>", lambda event: right_turn(tank))
plocha.bind("<Left>", lambda event: left_turn(tank))
plocha.focus_set()
plocha.pack()
plocha.mainloop()
Related
I have made a tkinter window which is round in shape.
I am trying to resize the window.
Everything works fine, but when I try to move it, it becomes square again.
I have added the code to draw the shape again, but still it becomes squared.
Here's the code:
from tkinter import Label, Tk, Canvas, BOTH, PhotoImage, Toplevel
from tkinter.constants import BOTTOM, E, NW, RAISED
import pyautogui as pg
root = Tk()
root.overrideredirect(1)
root.attributes("-transparentcolor", 'white')
root.attributes("-topmost", 1)
root.geometry("500x500")
# Creating a canvas for placing the squircle shape.
canvas = Canvas(root, height=500, width=500, highlightthickness=0, bg='white')
canvas.pack(fill=BOTH, expand=1)
def place_center(): # Placing the window in the center of the screen
global x, y
reso = pg.size()
rx = reso[0]
ry = reso[1]
x = int((rx/2) - (500/2))
y = int((ry/2) - (500/2))
root.geometry(f"500x500+{x}+{y}")
def move(event):
global rect
fx = root.winfo_pointerx() - 250
fy = root.winfo_pointery() - 10
root.geometry(f"500x500+{fx}+{fy}")
# if fx > 1 and fy > 1:
# canvas.delete(rect)
# rect = round_rectangle(0, 0, fx, fy, radius=50, fill="#1fa5fe")
def round_rectangle(x1, y1, x2, y2, radius=25, **kwargs): # Creating a rounded rectangle
points = [x1+radius, y1,
x1+radius, y1,
x2-radius, y1,
x2-radius, y1,
x2, y1,
x2, y1+radius,
x2, y1+radius,
x2, y2-radius,
x2, y2-radius,
x2, y2,
x2-radius, y2,
x2-radius, y2,
x1+radius, y2,
x1+radius, y2,
x1, y2,
x1, y2-radius,
x1, y2-radius,
x1, y1+radius,
x1, y1+radius,
x1, y1]
return canvas.create_polygon(points, **kwargs, smooth=True)
def cl(event):
root.quit()
def resize(event):
def end(event):
global rect
root.bind("<B1-Motion>", move)
global rect
global x, y
root.unbind("<B1-Motion>")
x = root.winfo_pointerx() - root.winfo_rootx()
y = root.winfo_pointery() - root.winfo_rooty()
if x > 0:
fx = root.winfo_rootx()
fy = root.winfo_rooty() + y
ht = root.winfo_height() - y
if ht > 0:
root.geometry(f"{x}x{ht}+{fx}+{fy}")
canvas.delete(rect)
rect = round_rectangle(0, 0, x, ht, radius=50, fill="#1fa5fe")
root.bind("<ButtonRelease-1>", end)
place_center()
# Creating the squircle
rect = round_rectangle(0, 0, 500, 500, radius=50, fill="#1fa5fe")
root.bind("<B1-Motion>", move)
root.bind("<Button-3>", cl)
rx = root.winfo_rootx()
ry = root.winfo_rooty()
side = Label(canvas, text=' \n', background="blue")
side.place(x=500-10, y=500-10)
side.bind("<B1-Motion>", resize)
root.unbind("<B1-Motion>")
root.mainloop()
Here're some images.
Before resizing:
After resizing and moving:
If you need, I am using Windows 10.
PS: Sorry if the code isn't written in good manner! I am creating this as a sample, which I will apply in my other apps when done.
Thank you.
NVM, I solved the problem.
When I was moving the window, it was set to default geometry, which made it look round.
I have changed it and here's the updated code for the move() function:
def move(event):
global rect
fx = root.winfo_pointerx() - 250
fy = root.winfo_pointery() - 10
try:
root.geometry(f"{x}x{ht}+{fx}+{fy}")
except Exception:
root.geometry(f"500x500+{fx}+{fy}")
The final code (with a few changes):
from tkinter import Label, Tk, Canvas, BOTH, PhotoImage, Toplevel
from tkinter.constants import BOTTOM, E, NW, RAISED, TOP
root = Tk()
root.overrideredirect(1)
root.attributes("-transparentcolor", 'white')
root.attributes("-topmost", 1)
root.geometry("500x500")
# Creating a canvas for placing the squircle shape.
canvas = Canvas(root, height=500, width=500, highlightthickness=0, bg='white')
canvas.pack(fill=BOTH, expand=1)
def place_center(): # Placing the window in the center of the screen
global x, y
rx = root.winfo_screenwidth()
ry = root.winfo_screenheight()
x = int((rx/2) - (500/2))
y = int((ry/2) - (500/2))
root.geometry(f"500x500+{x}+{y}")
def move(event):
global rect
fx = root.winfo_pointerx() - 250
fy = root.winfo_pointery() - 10
try:
root.geometry(f"{x}x{ht}+{fx}+{fy}")
except Exception:
root.geometry(f"500x500+{fx}+{fy}")
# if fx > 1 and fy > 1:
# canvas.delete(rect)
# rect = round_rectangle(0, 0, fx, fy, radius=50, fill="#1fa5fe")
def round_rectangle(x1, y1, x2, y2, radius=25, **kwargs): # Creating a rounded rectangle
points = [x1+radius, y1,
x1+radius, y1,
x2-radius, y1,
x2-radius, y1,
x2, y1,
x2, y1+radius,
x2, y1+radius,
x2, y2-radius,
x2, y2-radius,
x2, y2,
x2-radius, y2,
x2-radius, y2,
x1+radius, y2,
x1+radius, y2,
x1, y2,
x1, y2-radius,
x1, y2-radius,
x1, y1+radius,
x1, y1+radius,
x1, y1]
return canvas.create_polygon(points, **kwargs, smooth=True)
def cl(event):
root.quit()
def resize(event):
global rect
global x, y, ht
x = root.winfo_pointerx() - root.winfo_rootx()
y = root.winfo_pointery() - root.winfo_rooty()
if x > 0:
fx = root.winfo_rootx()
fy = root.winfo_rooty() + y
ht = root.winfo_height() - y
if ht > 0:
root.geometry(f"{x}x{ht}+{fx}+{fy}")
canvas.delete(rect)
rect = round_rectangle(0, 0, x, ht, radius=50, fill="#1fa5fe")
place_center()
top = Canvas(canvas, height=50, bg="#1fa5fe", highlightthickness=0)
top.pack(side=TOP, pady=2)
# Creating the squircle
rect = round_rectangle(0, 0, 500, 500, radius=50, fill="#1fa5fe")
top.bind("<B1-Motion>", move)
root.bind("<Button-3>", cl)
rx = root.winfo_rootx()
ry = root.winfo_rooty()
side = Label(canvas, text=' \n', background="blue")
side.place(x=500-10, y=500-10)
side.bind("<B1-Motion>", resize)
root.unbind("<B1-Motion>")
root.mainloop()
The following program draws a rectangle in the center of the canvas. The rectangle is supposed to get wider when the right arrow key is pressed, and narrower when the left arrow key is pressed.
Here's the code:
from tkinter import *
root = Tk()
canvas = Canvas(root, width=400, height=300, bg="#000000")
canvas.pack()
x1 = 150
y1 = 100
x2 = 250
y2 = 200
class ResizeRect:
def __init__(self, x1, y1, x2, y2):
self.x1 = x1
self.y1 = y1
self.x2 = x2
self.y2 = y2
self.rect = canvas.create_rectangle(0,0,1,1)
def draw(self):
canvas.delete(self.rect)
self.rect = canvas.create_rectangle(x1, y1, x2, y2,
outline="#00B000", width=2)
def narrower(self):
self.x1 = self.x1 + 5
self.x2 = self.x2 - 5
def wider(self):
self.x1 = self.x1 - 5
self.x2 = self.x2 + 5
r = ResizeRect(150, 100, 250, 200)
r.draw()
def left(event):
r.narrower()
r.draw()
def right(event):
r.wider()
r.draw()
canvas.bind_all('<KeyPress-Left>', left)
canvas.bind_all('<KeyPress-Right>', right)
My teacher told me that I need to add the 'self' keyword to the parameters in the draw function but I don't know what he means. (I can't ask him more because he's in a bad mood right now.). Any help is much appreciated.
I want to create a class and then an object which will display a red square in my display i also created.
At this moment, I can only display the blue square, which is not an object of the class "Baustein".
Here are my 2 files im using right now:
Bauklotz_class.py
from gui_backup import Display
class Baustein:
x1, y1, x2, y2 = 10,10,20,20
color = "red"
def __init__(self, x1, y1, x2, y2, color):
self.x1 = x1
self.x2 = x2
self.y1 = y1
self.y2 = y2
self.color = color
def show_new_object(self):
quadrat2 = Display.create_rectangle(40, 50, 60, 70, fill = color)
Display.coords(quadrat2, x1, y1, x2, y2)
gui_backup.py
from tkinter import *
import curses
import Bauklotz_class
x1 = 10 #initialise coordinates
y1 = 10
x2 = 20
y2 = 20
root = Tk() #create window
root.wm_title("Raspberry Pi GUI") #window title
root.config(background = "#FFFFFF") #background color
#The whole left frame and widgets involved
leftFrame = Frame(root, width=200, height = 400)
leftFrame.grid(row=0, column = 0, padx = 10, pady = 3)
leftLabel1 = Label(leftFrame, text = "Platzhalter Text")
leftLabel1.grid(row = 0, column = 0, padx = 10, pady = 3)
leftLabel2 = Label(leftFrame, text = "Dies ist ein Text\nmit mehreren Zeilen")
leftLabel2.grid(row = 1, column = 0, padx = 10, pady = 3)
#the whole right frame and widgets involved
rightFrame = Frame(root, width=400, height = 400)
rightFrame.grid(row = 0, column = 1, padx = 10, pady = 3)
E1 = Entry(rightFrame, width = 50)
E1.grid(row = 0, column = 0, padx = 10, pady = 60)
#The two functions for the 2 buttons created
def callback1():
test = Bauklotz_class.Baustein(20, 30, 40, 50, "red")
test.show_new_object()
def callback2():
print(1+1)
buttonFrame = Frame(rightFrame)
buttonFrame.grid(row = 1, column = 0, padx = 10, pady = 60)
B1 = Button(buttonFrame, text = "Button1", bg = "#FF0000", width = 15, command = callback1)
B1.grid(row = 0, column = 0, padx = 10, pady = 60)
B2 = Button(buttonFrame, text = "Button2", bg ="#FFFF00", width = 15, command = callback2)
B2.grid(row = 0, column = 1, padx = 10, pady = 60)
Slider = Scale(rightFrame, from_ = 0, to = 100, resolution = 0.1, orient = HORIZONTAL, length = 400)
Slider.grid(row = 2, column = 0, padx = 10, pady = 3)
Display = Canvas(rightFrame, width = 300, height = 300)
Display.configure(background = 'black')
Display.grid(row = 1, column = 3, padx = 10, pady = 3)
quadrat = Display.create_rectangle(20, 30, 40, 50, fill = "blue")
Display.coords(quadrat, x1, y1, x2, y2)
#following functions are for coordination of the square
#also you can find here the exceptions so that the object
#cant break out of the display widget
def down(event):
global x1, y1, x2, y2
if x2 == 290 or y2 == 300:
pass
else:
y1 += 10
y2 += 10
Display.coords(quadrat, x1, y1, x2, y2)
leftLabel1.config(text = "x1: " + str(x1) + ", x2:" + str(x2) + ", y1:" + str(y1) + ", y2:" + str(y2), width = "40" , )
def up(event):
global x1, y1, x2, y2
if x2 == 0 or y2 == 10:
pass
else:
y1 -= 10
y2 -= 10
Display.coords(quadrat, x1, y1, x2, y2)
leftLabel1.config(text = "x1: " + str(x1) + ", x2:" + str(x2) + ", y1:" + str(y1) + ", y2:" + str(y2), width = "40" , )
def left(event):
global x1, y1, x2, y2
if x1 == 0 or y1 == 10:
pass
else:
x1 -= 10
x2 -= 10
Display.coords(quadrat, x1, y1, x2, y2)
leftLabel1.config(text = "x1: " + str(x1) + ", x2:" + str(x2) + ", y1:" + str(y1) + ", y2:" + str(y2), width = "40" , )
def right(event):
global x1, y1, x2, y2
if x1 == 290 or y1 == 300:
pass
else:
x1 += 10
x2 += 10
Display.coords(quadrat, x1, y1, x2, y2)
leftLabel1.config(text = "x1: " + str(x1) + ", x2:" + str(x2) + ", y1:" + str(y1) + ", y2:" + str(y2), width = "40" , )
root.bind('<a>', left)
root.bind('<w>', up)
root.bind('<s>', down)
root.bind('<d>', right)
root.mainloop()
Now I only have the problem, that the following error is beeing generated: AttributeError: module 'Bauklotz_class' has no attribute 'Baustein'. I cant really figure out what python means by this, Im also a newbie in OOP, especialy in Python. Can someone help me with this problem?
Here is the full error message i get:
Exception in Tkinter callback Traceback (most recent call last):
File "/usr/lib/python3.5/tkinter/init.py", line 1562, in call
return self.func(*args) File "/home/pi/Documents/TKinter_Übung/gui_backup.py", line 31, in
callback1
test = Bauklotz_class.Baustein(20, 30, 40, 50, "red") AttributeError: module 'Bauklotz_class' has no attribute 'Baustein'
This line in your Callback1 function:
test = Bauklotz_class.Baustein()
needs 5 values in the brackets ('x1', 'y1', 'x2', 'y2', and 'color')
because it is calling your baustein class which ask for those parameters in the init function:
def __init__(self, x1, y1, x2, y2, color):
I have a problem with my project. I want my class Baustein to be a blueprint of an object I can place in my Display in the gui_backup.py. The program launches and everything works, but as I click the left button (button1) the same program opens again and now I have 2 programs going separately but I have no new Object in the Display created, just the old one which is being created in gui_backup in blue, but I want to create one in red with the class Baustein from Bauklotz_class.py. Here are my codes:
Bauklotz_class.py
from gui_backup import Display
class Baustein:
x1, y1, x2, y2 = 10,10,20,20
color = "red"
def __init__(self, x1, y1, x2, y2, color):
self.x1 = x1
self.x2 = x2
self.y1 = y1
self.y2 = y2
self.color = color
def show_new_object(self):
quadrat2 = Display.create_rectangle(40, 50, 60, 70, fill = color)
Display.coords(quadrat2, 40, 50, 60, 70)
gui_backup.py
from tkinter import *
import curses
x1 = 10 #initialise coordinates
y1 = 10
x2 = 20
y2 = 20
root = Tk() #create window
root.wm_title("Raspberry Pi GUI") #window title
root.config(background = "#FFFFFF") #background color
#The whole left frame and widgets involved
leftFrame = Frame(root, width=200, height = 400)
leftFrame.grid(row=0, column = 0, padx = 10, pady = 3)
leftLabel1 = Label(leftFrame, text = "Platzhalter Text")
leftLabel1.grid(row = 0, column = 0, padx = 10, pady = 3)
leftLabel2 = Label(leftFrame, text = "Dies ist ein Text\nmit mehreren Zeilen")
leftLabel2.grid(row = 1, column = 0, padx = 10, pady = 3)
#the whole right frame and widgets involved
rightFrame = Frame(root, width=400, height = 400)
rightFrame.grid(row = 0, column = 1, padx = 10, pady = 3)
E1 = Entry(rightFrame, width = 50)
E1.grid(row = 0, column = 0, padx = 10, pady = 60)
#The two functions for the 2 buttons created
def callback1():
import Bauklotz_class
test = Bauklotz_class.Baustein(20, 30, 40, 50, "red")
test.show_new_object()
def callback2():
print(1+1)
buttonFrame = Frame(rightFrame)
buttonFrame.grid(row = 1, column = 0, padx = 10, pady = 60)
B1 = Button(buttonFrame, text = "Button1", bg = "#FF0000", width = 15, command = callback1)
B1.grid(row = 0, column = 0, padx = 10, pady = 60)
B2 = Button(buttonFrame, text = "Button2", bg ="#FFFF00", width = 15, command = callback2)
B2.grid(row = 0, column = 1, padx = 10, pady = 60)
Slider = Scale(rightFrame, from_ = 0, to = 100, resolution = 0.1, orient = HORIZONTAL, length = 400)
Slider.grid(row = 2, column = 0, padx = 10, pady = 3)
Display = Canvas(rightFrame, width = 300, height = 300)
Display.configure(background = 'black')
Display.grid(row = 1, column = 3, padx = 10, pady = 3)
quadrat = Display.create_rectangle(20, 30, 40, 50, fill = "blue")
Display.coords(quadrat, x1, y1, x2, y2)
#following functions are for coordination of the square
#also you can find here the exceptions so that the object
#cant break out of the display widget
def down(event):
global x1, y1, x2, y2
if x2 == 290 or y2 == 300:
pass
else:
y1 += 10
y2 += 10
Display.coords(quadrat, x1, y1, x2, y2)
leftLabel1.config(text = "x1: " + str(x1) + ", x2:" + str(x2) + ", y1:" + str(y1) + ", y2:" + str(y2), width = "40" , )
def up(event):
global x1, y1, x2, y2
if x2 == 0 or y2 == 10:
pass
else:
y1 -= 10
y2 -= 10
Display.coords(quadrat, x1, y1, x2, y2)
leftLabel1.config(text = "x1: " + str(x1) + ", x2:" + str(x2) + ", y1:" + str(y1) + ", y2:" + str(y2), width = "40" , )
def left(event):
global x1, y1, x2, y2
if x1 == 0 or y1 == 10:
pass
else:
x1 -= 10
x2 -= 10
Display.coords(quadrat, x1, y1, x2, y2)
leftLabel1.config(text = "x1: " + str(x1) + ", x2:" + str(x2) + ", y1:" + str(y1) + ", y2:" + str(y2), width = "40" , )
def right(event):
global x1, y1, x2, y2
if x1 == 290 or y1 == 300:
pass
else:
x1 += 10
x2 += 10
Display.coords(quadrat, x1, y1, x2, y2)
leftLabel1.config(text = "x1: " + str(x1) + ", x2:" + str(x2) + ", y1:" + str(y1) + ", y2:" + str(y2), width = "40" , )
root.bind('<a>', left)
root.bind('<w>', up)
root.bind('<s>', down)
root.bind('<d>', right)
root.mainloop()
Here are also some screenshots for you to understand it better:
Does someone know why my project is duplicating itself?
The problem lies within your double import, i guess. You see, you import from gui_backup.py into Bauklotz_class.py, while also importing vice versa, which leads to weird and unexpected behaviour. Also, inside the definition of show_new_object, you should use self.color instead of color as an argument for Display.create_rectangle, because self.color is a class attribute and thus the proper object to use in a class method definition. One way to fix your Problem is to add an additional attribute, let's call it canvas, to Baustein, and removing the import Display, so Bauklotz_class.py now looks like this:
class Baustein():
x1, y1, x2, y2 = 10, 10, 20, 20
color = "red"
def __init__(self, x1, y1, x2, y2, color, canvas):
self.x1 = x1
self.x2 = x2
self.y1 = y1
self.y2 = y2
self.color = color
self.canvas=canvas
def show_new_object(self):
quadrat2 = self.canvas.create_rectangle(40, 50, 60, 70, fill=self.color)
self.canvas.coords(quadrat2, 40, 50, 60, 70)
And then call it like this in gui_backup.py:
...
def callback1():
import Bauklotz_class
test = Bauklotz_class.Baustein(20, 30, 40, 50, "red", Display)
test.show_new_object()
which will fix your problem, and create a red rectangle instead of duplicating your window.
So I'm creating a script to test tkinter, which is supposed to generate random rectangles on a canvas. Here is my script:
from Tkinter import *
import random
tk = Tk()
canvas = Canvas(tk, width=400, height=400)
canvas.pack()
Option = StringVar()
Option.set("None")
menu = OptionMenu(tk, Option,"None", "Colored Outlines", "Colored Fills")
menu.pack()
option = Option.get()
button = button = Button(tk, text="Generate", command="Generate")
button.pack()
colors = ['red', 'orange', 'yellow', 'green', 'blue', 'purple']
def random_rectangle(width, height):
x1 = random.randrange(width)
y1 = random.randrange(height)
x2 = x1 + random.randrange(width)
y2 = y1 + random.randrange(height)
canvas.create_rectangle(x1, y1, x2, y2)
def random_outline_rectangle(width, height):
x1 = random.randrange(width)
y1 = random.randrange(height)
x2 = x1 + random.randrange(width)
y2 = y1 + random.randrange(height)
color = random.choice(colors)
canvas.create_rectangle(x1, y1, x2, y2, outline = color)
def random_color_rectangle(width, height):
x1 = random.randrange(width)
y1 = random.randrange(height)
x2 = x1 + random.randrange(width)
y2 = y1 + random.randrange(height)
color = random.choice(colors)
canvas.create_rectangle(x1, y1, x2, y2, fill = color)
def Generate():
global option
if option == "None":
for x in range(0,100):
random_rectangle(400, 400)
elif option == "Colored Outlines":
for x in range(0,100):
random_outline_rectangle(400,400)
elif option == "Colored Fills":
for x in range(0,1000):
random_color_rectangle(400,400)
tk.mainloop()
So my code works perfecty without the generate button (If I remove def Generate:()) but when I run it with that, and press the button, it does nothing. Without, you must set the option by changing the code at Option.set(). I do not understand why pressing the button does nothing, however, with the original code. Any help? And how can I fix this?
Ok, I found my solution. Rawing was right, but I also needed to move the button creation to after I defined all my functions. The updated code is as follows:
from Tkinter import *
import random
tk = Tk()
canvas = Canvas(tk, width=400, height=400)
canvas.pack()
Option = StringVar()
Option.set("None")
menu = OptionMenu(tk, Option,"None", "Colored Outlines", "Colored Fills")
menu.pack()
colors = ['red', 'orange', 'yellow', 'green', 'blue', 'purple']
def random_rectangle(width, height):
x1 = random.randrange(width)
y1 = random.randrange(height)
x2 = x1 + random.randrange(width)
y2 = y1 + random.randrange(height)
canvas.create_rectangle(x1, y1, x2, y2)
def random_outline_rectangle(width, height):
x1 = random.randrange(width)
y1 = random.randrange(height)
x2 = x1 + random.randrange(width)
y2 = y1 + random.randrange(height)
color = random.choice(colors)
canvas.create_rectangle(x1, y1, x2, y2, outline=color)
def random_color_rectangle(width, height):
x1 = random.randrange(width)
y1 = random.randrange(height)
x2 = x1 + random.randrange(width)
y2 = y1 + random.randrange(height)
color = random.choice(colors)
canvas.create_rectangle(x1, y1, x2, y2, fill=color, outline=color)
def Generate():
global option
canvas.delete("all")
if Option.get() == "None":
for x in range(0,100):
random_rectangle(400, 400)
elif Option.get() == "Colored Outlines":
for x in range(0,100):
random_outline_rectangle(400,400)
elif Option.get() == "Colored Fills":
for x in range(0,1000):
random_color_rectangle(400,400)
button = button = Button(tk, text="Generate", command=Generate)
button.pack()
tk.mainloop()