I'm having trouble with getting the turtle.begin_fill() / turtle.end_fill() commands to work in a tkinter window. I want to have the program draw a bunch of coloured cells onto the screen in a 64x32 grid. This the whole code to set up the window and draw however it simply doesn't do anything after setting up a window:
import turtle as tu
import tkinter as tk
axis = []
num = -512
for i in range(0,64):
axis.append(num)
num = num + 16
def drawworld(*args):
for i in range(0,64):
for j in range(0,32):
tu.goto(axis[i],axis[j]+256)
tu.pd()
tu.color=("#ffff00")
tu.begin_fill()
for k in range(0,4):
tu.fd(16)
tu.lt(90)
tu.end_fill()
tu.pu()
root = tk.Tk()
root.title("game")
root.resizable(False, False)
canvas = tk.Canvas(master = root, width = 1024, height = 512)
canvas.grid(row=0, column=0, columnspan=10)
tu = tu.RawTurtle(canvas)
tu.speed(50)
tu.pu()
tu.ht()
drawworld()
root.mainloop()
however, if I were to comment out the fill lines, the code works perfectly (without colouring the boxes) which means there must be something wrong with:
tu.color=("#ffff00")
tu.begin_fill()
for k in range(0,4):
tu.fd(16)
tu.lt(90)
tu.end_fill()
tu.pu()
I've looked up the documentation and this should be perfect syntax. What am I doing wrong?
I believe your problem is this line:
tu.color=("#ffff00")
which probably should be:
tu.color("#ffff00")
to set the color, you don't assign to the turtle's color property but rather invoke the turtle's .color() method. Your code with this change and some other cleanup:
import tkinter as tk
from turtle import RawTurtle
axis = []
num = -512
for _ in range(64):
axis.append(num)
num += 16
def drawworld():
for i in range(64):
for j in range(32):
tu.goto(axis[i], axis[j] + 256)
tu.pendown()
tu.color("#ffff00")
tu.begin_fill()
for _ in range(4):
tu.forward(16)
tu.left(90)
tu.end_fill()
tu.penup()
root = tk.Tk()
root.title("game")
root.resizable(False, False)
canvas = tk.Canvas(master=root, width=1024, height=512)
canvas.grid(row=0, column=0, columnspan=10)
tu = RawTurtle(canvas)
tu.speed('fastest')
tu.hideturtle()
tu.penup()
drawworld()
root.mainloop()
However, this is a painfully slow way to go about this. There are faster ways, here's one that uses stamping to speed up the process:
import tkinter as tk
from turtle import RawTurtle
from random import random
CUBE_SIZE = 16
CURSOR_SIZE = 20
WIDTH, HEIGHT = 1024, 512
axis = []
num = -HEIGHT
for _ in range(WIDTH // CUBE_SIZE):
axis.append(num)
num += CUBE_SIZE
def drawworld():
for i in range(WIDTH // CUBE_SIZE):
tu.goto(axis[i] + CUBE_SIZE // 2, axis[0] + HEIGHT // 2 + CUBE_SIZE // 2)
for j in range(HEIGHT // CUBE_SIZE):
tu.color(random(), random(), random())
tu.stamp()
tu.forward(CUBE_SIZE)
root = tk.Tk()
root.title("game")
root.resizable(False, False)
canvas = tk.Canvas(master=root, width=WIDTH, height=HEIGHT)
canvas.grid(row=0, column=0, columnspan=10)
tu = RawTurtle(canvas)
tu.shape('square')
tu.shapesize(CUBE_SIZE / CURSOR_SIZE)
tu.speed('fastest')
tu.hideturtle()
tu.setheading(90)
tu.penup()
drawworld()
root.mainloop()
Related
please tell me how to change the position of the button in tkinter. I predicted that it could be done by button['padx' = 4], but it doesn't work. Do you know how to do it?
from tkinter import ttk
import random
window = tk.Tk()
window.geometry('512x512')
def click():
pass
button = ttk.Button(
text="No",
command=click
).pack(padx=5, pady=15)
window.mainloop()
I instead assigned 2 variables to random integers, and then updated the position of the button with those variables. If you want the random position to be a wider area increase the number "100" in "random_int".
from tkinter import *
import random
window = Tk()
window.geometry('512x512')
x = 5
y = 15
def click():
random_int = random.randint(0, 100)
x = (random_int)
random_int = random.randint(0, 100)
y = (random_int)
button.place(x=x, y=y)
button = Button(text="No", command=click)
button.pack(padx=5, pady=15)
window.mainloop()
I want to move a rectangle from left to right with a step of 50,but the canvas doesn't draw the rectangle until it arrive right side.
import tkinter as tk
import time
root=tk.Tk()
c_width,c_height=500,250
cv = tk.Canvas(root,bg = 'white',width=c_width,height=c_height)
l_x=0
l_y=0
r_x=50
r_y=50
step=50
r1=cv.create_rectangle(l_x,l_y,r_x,r_y,fill='red')
while l_x<c_width-50:
cv.delete(r1)
l_x=l_x+step
r_x=r_x+step
r1=cv.create_rectangle(l_x,l_y,r_x,r_y,fill='red')
print(c_width,l_x)
time.sleep(1)
cv.pack()
root.mainloop()
It is not recommended to use while/for loop in tkinter application because it will block the tkinter mainloop() from handling pending events and updates. Use .after() instead.
Also you don't need to delete and recreate the rectangle item, just move the rectangle item using cv.move().
Below is the update code:
import tkinter as tk
root = tk.Tk()
c_width, c_height = 500, 250
cv = tk.Canvas(root, bg='white', width=c_width, height=c_height)
cv.pack()
l_x = 0
l_y = 0
r_x = 50
r_y = 50
step = 50
r1 = cv.create_rectangle(l_x, l_y, r_x, r_y, fill='red')
def move_rect(x):
# move the rectangle by "step" pixels horizontally
cv.move(r1, step, 0)
x += step
if x < c_width:
cv.after(1000, move_rect, x)
cv.after(1000, move_rect, r_x)
root.mainloop()
I am trying to build a GUI based code, where there will be a splashcreen, a wait for 5 seconds and then the main GUI should show up. I am using Python 3.6. Here is my code:
from tkinter import Tk, PhotoImage, Canvas, Label
from time import sleep
root = Tk()
root.overrideredirect(True)
width = root.winfo_screenwidth()
height = root.winfo_screenheight()
image_file = 'splash_fig.png'
splashImage = PhotoImage(file = image_file)
w = splashImage.width()
h = splashImage.height()
y = int((height - h) / 2)
x = int((width - w) / 2)
root.geometry('%dx%d+%d+%d' % (w,h,x,y))
canvas = Canvas(root,height = h, width = w, bg = "brown")
canvas.create_image(0,0,image = splashImage, anchor='nw')
canvas.pack()
root.after(5000, root.destroy)
root.mainloop()
root = Tk()
my_label = Label(root, text="Something something")
my_label.pack()
root.mainloop()
What is happening is that the splashscreen does not show up, but the second GUI does! Where is the exact problem here! My question is an extension to this question, where I have closely followed the solution proposed
I would like print all the information present in the excel data in new tkinter window
You can use Tkinter's grid.
For example, to create a simple excel-like table:
from Tkinter import *
root = Tk()
height = 5
width = 5
for i in range(height): #Rows
for j in range(width): #Columns
b = Entry(root, text="")
b.grid(row=i, column=j)
mainloop()
To print, consider the following example in which I make a button with Tkinter that gets some text from a widget and then prints it to console using the print() function.
from tkinter import *
from tkinter import ttk
def print_text(*args):
try:
print(text1.get())
except ValueError:
pass
root = Tk()
root.title("Little tkinter app for printing")
mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column = 0, row = 0, sticky = (N,W,E,S))
mainframe.columnconfigure(0, weight = 1)
mainframe.rowconfigure(0, weight = 1)
text1 = StringVar()
text_entry = ttk.Entry(mainframe, width = 20, textvariable=text1)
text_entry.grid(column = 1, row = 2, sticky = (N,W,E,S))
ttk.Button(mainframe, text = "Print!", command =
print_text(text1)).grid(column = 1, row = 3, sticky = (E))
for child in mainframe.winfo_children():
child.grid_configure(padx = 5, pady = 5)
text_entry.focus()
root.bind('<Return>', print_text)
root.mainloop()
Ok guys.
I am trying to generate 10 balls of random color in Tkinter canvas when I click the generate button.
Program works, and random color choice works for the ball, but I only get one ball generated at a time.
Every time I click the button it randomly moves the ball around, but all I want is 10 balls in 10 random positions at a time. I am using Python 3.4 on a Linux box.
This is a code I've got:
from tkinter import *
import random # to generate random balls
colors = ["red", "blue", "purple", "green", "violet", "black"]
class RandomBalls:
"""
Boilerplate code for window in Tkinter
window = Tk()
window.title("Random title")
window.mainloop()
"""
def __init__(self):
"""
Initialize the window and add two frames, one with button, and another one with
canvas
:return:
"""
window = Tk()
window.title("Random balls")
# A canvas frame
frame1 = Frame(window)
frame1.pack()
self.canvas = Canvas(frame1, width = 200, height = 300, bg = "white")
self.canvas.pack()
# A button frame
frame2 = Frame(window)
frame2.pack()
displayBtn = Button(frame2, text = "Display", command = self.display)
displayBtn.pack()
window.mainloop()
def display(self):
for i in range(0, 10):
self.canvas.delete("circle") # delete references to the old circle
self.x1 = random.randrange(150)
self.y1 = random.randrange(200)
self.x2 = self.x1 + 5
self.y2 = self.y1 + 5
self.coords = self.x1, self.y1, self.x2, self.y2
self.canvas.create_oval(self.coords, fill = random.choice(colors), tags = "circle")
self.canvas.update()
RandomBalls()
Every time through your loop you are deleting everything you created before, including what you created the previous iteration. Move the delete statement outside of the loop:
def display(self):
self.canvas.delete("circle")
for i in range(0, 10):
...