Combining python turtle and tkinter` - python

I need to combine python turtle and tkinter for tic tac toe game, I looked at some sites and tried, but it didn't worked as I imagine, so I need help.
Code:
from turtle import *
from circle import Tac
from cross import Tic
from tkinter import *
screen = Screen()
screen.title("Tic Tac Toe")
screen.setup(width=300, height=500)
tim = Turtle()
board = "board.gif"
screen.addshape(board)
img_turtle = Turtle()
img_turtle.shape(board)
screen.listen()
tim.penup()
tim.seth(0)
Code I want to add:
button1 = Button(text="button", command=tic.one)
button1.place(x=-70, y=42)

Python turtle is designed to operate either standalone or embedded in a larger tkinter program. You're trying to use the standalone interface in an embedded situation. Below is my rework of what I would have expected your code to look like. Since you didn't provide a runnable example, this is an incomplete sketch:
from tkinter import *
from turtle import RawTurtle, TurtleScreen
from circle import Tac
from cross import Tic
BOARD = "board.gif"
root = Tk()
root.title("Tic Tac Toe")
canvas = Canvas(root, width=300, height=500)
canvas.pack(side=LEFT)
screen = TurtleScreen(canvas)
screen.addshape(BOARD)
tim = RawTurtle(screen)
tim.penup()
img_turtle = RawTurtle(screen)
img_turtle.shape(BOARD)
button = Button(root, text="button", command=tic.one)
button.pack()
screen.mainloop()

Related

tkinter tic tac toe board not formatted correctly

There is spacing around the tic-tac-toe board that I don't know how to fix. If I remove all labels it fixes. For reference, this is a project for school and I'm unable to use any other config and grid options.
def button(window,row,column):
button=tkinter.Button(window)
#confiC3details
button.config(text='')
button.config(font=['comic sans ms',20])
button.config(bg='#ffffff')
button.config(width=5)
button.grid(row=row)
button.grid(column=column)
def createGameBoard(window):
def playTicTacToe():
window=createWindow()
title=createTitle(window)
# player1label=createPlayer1Label(window)
# Create the components for the game
# Setup the commands for all the different buttons
button(window,1,1)
button(window,1,2)
button(window,1,3)
button(window,2,1)
button(window,2,2)
button(window,2,3)
button(window,3,1)
button(window,3,2)
button(window,3,3)
# Start the game
window.mainloop()
# =============================================================
#Start the tic-tac-toe game
playTicTacToe()
I tried padx and pady but that didn't change anything.
You can try my example.
import tkinter as tk
root = tk.Tk()
b1=tk.Button(root,width=20,height=10)
b1.grid(row=1,column=1)
b2=tk.Button(root,width=20,height=10)
b2.grid(row=1,column=2)
b3=tk.Button(root,width=20,height=10)
b3.grid(row=1,column=3)
b4=tk.Button(root,width=20,height=10)
b4.grid(row=2,column=1)
b5=tk.Button(root,width=20,height=10)
b5.grid(row=2,column=2)
b6=tk.Button(root,width=20,height=10)
b6.grid(row=2,column=3)
b7=tk.Button(root,width=20,height=10)
b7.grid(row=3,column=1)
b8=tk.Button(root,width=20,height=10)
b8.grid(row=3,column=2)
b9=tk.Button(root,width=20,height=10)
b9.grid(row=3,column=3)
root.mainloop()

Is there a way to implant tkinter input box into my turtle screen (to create paint)

I have this code taken from trinket.io
import turtle
tina = turtle.Turtle()
tina.shape("turtle")
# promt user for color and make turtle that color
turtle_color = input("What color should tina the turtle be?")
tina.color(turtle_color)
# promt user for background color and makes it that color
myscreen = turtle.Screen()
background_color = input("What color should background be?")
myscreen.bgcolor(background_color)
What I would like to do is that I would like to merge my tkinter inputbox into one side of the program and create a sort of paint like program
this is the code for tkinter button:
from tkinter import *
master = Tk()
e = Entry(master)
e.pack()
e.focus_set()
def callback():
print e.get() # This is the text you may want to use later
b = Button(master, text = "OK", width = 10, command = callback)
b.pack()
mainloop()
we could also merge it with the turtle demo program in python which could sort of create paint..
So I just wanted to know how to merge them
by merging I mean the tkinter button and input box in one side of the turtle
answer is still accepted.. thank you
Although the answers you've received so far work, I argue that they are assembled backward, if not incorrectly. The hint is their use of an undocumented interface:
root = screen._root
assert isinstance(tina.screen._root, tk.Tk)
Turtle knows it's implemented in tkinter, and along with the standard standalone interface, it documents an embedded interface for when you mix turtle with tkinter. Reworking #volothud's example:
import tkinter as tk
from tkinter.simpledialog import askstring
from turtle import TurtleScreen, RawTurtle
root = tk.Tk()
canvas = tk.Canvas(root, width=600, height=480)
canvas.pack()
distance = tk.IntVar()
controls = tk.Frame(root)
tk.Label(controls, text="Move forward:").pack(side=tk.LEFT)
tk.Entry(controls, textvariable=distance).pack(side=tk.LEFT)
tk.Button(controls, text="Go!", command=lambda: turtle.forward(distance.get())).pack(side=tk.LEFT)
controls.pack()
turtle_color = askstring("Turtle's color", "What color should the turtle be?")
background_color = askstring("Background color", "What color should the background be?")
screen = TurtleScreen(canvas)
screen.bgcolor(background_color)
turtle = RawTurtle(screen)
turtle.shape('turtle')
turtle.color(turtle_color)
root.mainloop()
Otherwise, if you're not careful, you can end up with two roots. This can cause bugs further down the road, like unexplainable errors upon loading images.
Turtle is based on Tkinter, so there is a way to embed other Tkinter widgets to Turtle programs. You can do it in several ways:
go with #cdlane's answer. It is the cleanest one and it uses Turtle's documented interface, specially designed for embedding it in Tkinter apps.
take a look at the second part of #volothud's answer (the first one is described below).
You just need either to specify myscreen._root as a master of a widget or to use myscreen._canvas in another Tkinter window.
Here is an example for the third option:
import tkinter as tk
from tkinter.simpledialog import askstring
import turtle
tina = turtle.Turtle()
tina.shape("turtle")
screen = turtle.Screen()
root = screen._root
controls = tk.Frame(root)
tk.Label(controls, text="Move forward:").pack(side=tk.LEFT)
fwd_entry = tk.Entry(controls)
fwd_entry.pack(side=tk.LEFT)
tk.Button(controls, text="Go!", command=lambda: tina.forward(int(fwd_entry.get()))).pack(side=tk.LEFT)
controls.pack()
tina_color = askstring("Tina's color", "What color should Tina the turtle be?")
bg_color = askstring("The background color", "What color should the background be?")
tina.color(tina_color)
screen.bgcolor(bg_color)
root.mainloop()
Note 1: why are you using input(...) (which is for terminal/command-line) together with GUI? You can use tkinter.simpledialog instead (see the code snippet above).
Note 2: Inputs are not validated, so the user can enter anything (you can catch them with try/except and show the error dialog with tkinter.messagebox).
It seems fine. Just merge your turtle & tkinter code, e.g.:
import tkinter as tk
import turtle
# Setup turtle
tina = turtle.Turtle()
tina.shape("turtle")
tina.color('red')
myscreen = turtle.Screen()
myscreen.bgcolor('black')
# Setup GUI
# Use independent Tk root:
#root = tk.Tk()
# Use the same Tk root with turtle:
assert isinstance(tina.screen._root, tk.Tk) # True
root = tina.screen._root
distVar = tk.IntVar(root)
distEntry = tk.Entry(root, textvariable=distVar)
distEntry.pack()
distEntry.focus_set()
def moveFwd():
tina.forward(distVar.get())
fwdBtn = tk.Button(root, text='MoveFwd', command=moveFwd)
fwdBtn.pack()
# After setup is done (turtle, widgets & event-callbacks),
# enter event-loop (&react to user input in event-callbacks)
root.mainloop()
Just so people stop quoting the original example as "bad",
here's an even simpler one:
(Again, these are all just options (for a simple problem).)
import tkinter as tk
import turtle
# Setup turtle.
# This will create a Tk root, that can be implicitly reused.
t = turtle.Turtle()
# Setup tkinter GUI.
distVar = tk.IntVar()
distEntry = tk.Entry(textvariable=distVar)
distEntry.pack()
distEntry.focus_set()
def moveFwd(): t.forward(distVar.get())
fwdBtn = tk.Button(text='MoveFwd', command=moveFwd)
fwdBtn.pack()
# After setup is done (turtle, widgets & event-callbacks),
# enter event-loop (&react to user input in event-callbacks)
tk.mainloop() # Also known as "turtle.done()".

Tkinter get width of button made with `create_window()`

I'm using Tkinter combined with Python Turtle Graphics and I want to be able to get the width of a button made using create_window().
I am able to set the value using the code below, but I want to get the value rather than set it. How do I do this please?
import turtle
import tkinter as tk
screen = turtle.Screen()
canvas = screen.getcanvas()
button = tk.Button(canvas.master, text="Press me")
w1 = canvas.create_window(0, 0, window=button)
canvas.itemconfig(w1, width=100)
turtle.done()
This will do it.
import turtle
import tkinter as tk
screen = turtle.Screen()
canvas = screen.getcanvas()
button = tk.Button(canvas.master, text="Press me")
w1 = canvas.create_window(0, 0, window=button)
canvas.itemconfig(w1, width=100)
button.update()
print(button.winfo_width())
print(button.winfo_height())
turtle.done()
Make sure to update before calling .winfo_width(). :-)

How to speed up the turtle while in a tkinter canvas

I'm trying to make the turtle move faster, which I would normally do using
import turtle as t
t.speed(0)
t.tracer(0,0)
But when I have it in a canvas using RawTurtle(), I'm not sure how to do this.
root = tk.Tk() #create root window
#create turtle canvas
canvas = tk.Canvas(root,width=500,height=500)
canvas.pack()
t = turtle.RawTurtle(canvas)
t.ht()
Here's my code. Anyone know how?
First, either do one or the other of these, not both:
t.speed(0)
t.tracer(0,0)
The speed(0) aka speed('fastest') gets you the fastest drawing animation. The tracer(0) eliminates drawing animation altogether. They don't add together.
You can get maximum speed, i.e. eliminate drawing animation, in turtle embedded in a Canvas by using turtle's TurtleScreen() wrapper:
import tkinter as tk
from turtle import TurtleScreen, RawTurtle
root = tk.Tk()
canvas = tk.Canvas(root, width=500, height=500)
canvas.pack()
screen = TurtleScreen(canvas)
screen.tracer(False)
turtle = RawTurtle(screen)
turtle.circle(100)
screen.tracer(True)
screen.mainloop()
I made a few edits to your code. For starters, you need to work all the commands after the t = turtle.RawTurtle(canvas) line. Then you need to add a .mainloop() function at the end.
This would be your final code:
import tkinter as tk
root = tk.Tk() #create root window
import turtle
#create turtle canvas
canvas = tk.Canvas(root,width=500,height=500)
canvas.pack()
t = turtle.RawTurtle(canvas)
t.speed(1)
t.forward(100)
t.ht()
root.mainloop()
When the speed is set to 1, this is the output:
When the speed is set to 0, this is the output:
Sorry about the gifs, and hope this helps!

Trying to take user input and make a turtle dot

Trying to take user input in this case a numbers and make a turtle make a dot with the number that we got from the user input. It is for a school project that I am trying to do and I tried finding YouTube videos they really did not help.
from tkinter import *
import tkinter
import turtle
wn = turtle.Screen()
wn.bgcolor('black')
player = turtle.Turtle()
player.shape('turtle')
player.color('white')
def sad():
player.dot(str(kj.get()))
top = tkinter.Tk()
top.geometry('600x600')
kj = Entry(top, bd =5)
kj.pack()
B = tkinter.Button(top, text ="Hello", command = sad)
B.pack()
wn.mainloop()
top.mainloop()
When using Python turtle in conjunction with tkinter, you need to use the embedded turtle methods, not the standalone methods you used. As turtle is built atop tkinter, you've effectively created two roots and will eventually run into trouble. (E.g. images probably won't work for you.) You're clearly confused by the combination as you call both top.mainloop() and wn.mainloop()!
Here's an example of how to embed turtle in tkinter for your program:
import tkinter as tk
from turtle import TurtleScreen, RawTurtle
def set_position():
player.setposition(x_entry.get(), y_entry.get())
player.dot(30, 'blue')
player.home()
top = tk.Tk()
canvas = tk.Canvas(top, width=600, height=600)
canvas.pack()
screen = TurtleScreen(canvas)
screen.bgcolor('black')
player = RawTurtle(screen)
player.shape('turtle')
player.color('red', 'white')
player.penup()
x_entry = tk.DoubleVar()
tk.Label(top, text="X: ").pack(side=tk.LEFT)
tk.Entry(top, textvariable=x_entry).pack(side=tk.LEFT)
y_entry = tk.DoubleVar()
tk.Label(top, text="Y: ").pack(side=tk.LEFT)
tk.Entry(top, textvariable=y_entry).pack(side=tk.LEFT)
tk.Button(top, text="Draw Dot!", command=set_position).pack()
screen.mainloop()
My recommendations are: first, try to work completely within standalone turtle if you can, and not introduce tkinter unless you really need to; second, don't trust any answer that makes this same mistake of trying to use standalone turtle classes embedded in a tkinter environment.
with turtle you can tell it to go to a position using setPos commands. If you just convert the values from your user input into coordinates, tell you turtle to go there and then start drawing.
Here is a solution:
import turtle
from time import sleep
from tkinter import *
#Setup
root=Tk()
wn = turtle.Screen()
wn.bgcolor('black')
player = turtle.Turtle()
player.shape('turtle')
player.color('white')
def goToLocation(coords):
#Get user input and split it into two different coordinants (coordsx and coordsy)
coordsx, coordsy = coords.split(" ")
#Set turtles position to the coords specified
player.hideturtle()
player.penup()
player.setpos(int(coordsx),int(coordsy))
#Draw the circle of size
player.pensize(50)
player.showturtle()
player.pendown()
player.forward(1)
sleep(5)
#Button clicked handler
def retrieve_input():
inputValue=textBox.get("1.0","end-1c")
print(inputValue)
#Calls the previous function
goToLocation(inputValue)
#Input box setup
textBox=Text(root, height=2, width=10)
textBox.pack()
buttonCommit=Button(root, height=1, width=10, text="Commit",
command=lambda: retrieve_input())
#command=lambda: retrieve_input() >>> just means do this when i press the button
buttonCommit.pack()
mainloop()

Categories