Use tkinter buttons to control a Python turtle in another window - python

I'm trying to use tkinter's buttons to control a turtle in another graphics window, but the buttons don't function
I was trying to use turtle graphics and Tkinter to make a simple program that controls a turtle with buttons. However, it seems that only one button is actually running a function, and even that is producing an error. Here is the code I wrote:
from tkinter import *
import turtle
global x
global y
x = 1
y = 1
i = 0
root = Tk()
wn = turtle.Screen()
bob = turtle.Turtle()
bob.up()
def goUp(event):
y=y+5
bob.goto(x,y)
def goDown(event):
y=y-5
bob.goto(x,y)
def goRight(event):
x=x+5
bob.goto(x,y)
def goLeft(event):
x=x-5
bob.goto(x,y)
topFrame = Frame(root)
topFrame.pack()
middleFrame = Frame(root)
middleFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack()
button1 = Button(topFrame, text = "Up", fg="red")
button2 = Button(middleFrame, text = "Left", fg="red")
button3 = Button(middleFrame, text = "Right", fg="red")
button4 = Button(bottomFrame, text = "Down", fg="red")
button1.bind("<Button-1>", goUp)
button2.bind("<Button-2>", goLeft)
button3.bind("<Button-3>", goRight)
button4.bind("<Button-4>", goDown)
button1.pack()
button2.pack(side=LEFT)
button3.pack(side=RIGHT)
button4.pack()
root.mainloop()

The TKinter Button class accepts a command option where you can pass in the function that gets called when a button is pressed. You also need to access the global x and y variables inside your methods.
Try this code:
from tkinter import *
import turtle
global x
global y
x = 1
y = 1
i = 0
root = Tk()
wn = turtle.Screen()
bob = turtle.Turtle()
bob.up()
def goUp():
global x, y
y=y+5
bob.goto(x,y)
def goDown():
global x, y
y=y-5
bob.goto(x,y)
def goRight():
global x, y
x=x+5
bob.goto(x,y)
def goLeft():
global x, y
x=x-5
bob.goto(x,y)
topFrame = Frame(root)
topFrame.pack()
middleFrame = Frame(root)
middleFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack()
button1 = Button(topFrame, text = "Up", fg="red", command=goUp)
button2 = Button(middleFrame, text = "Left", fg="red", command=goLeft)
button3 = Button(middleFrame, text = "Right", fg="red", command=goRight)
button4 = Button(bottomFrame, text = "Down", fg="red", command=goDown)
button1.pack()
button2.pack(side=LEFT)
button3.pack(side=RIGHT)
button4.pack()
root.mainloop()

Turtle's Turtle and Screen classes are generally used when turtle.py is used standalone. When turtle, which is implemented atop tkinter, is used embedded inside tkinter, we generally use the RawTurtle and TurtleScreen classes instead. You'll find more about this in the turtle documentation
You also should review one of the many online Python global keyword tutorials as you're not using it correctly. Fortunately, we don't need it to implement this particular program.
Here's a rework of your code, as a single window implementation, that illustrates the above:
import tkinter as tk
from turtle import RawTurtle, TurtleScreen
def goUp():
bob.sety(bob.ycor() + 5)
def goDown():
bob.sety(bob.ycor() - 5)
def goRight():
bob.setx(bob.xcor() + 5)
def goLeft():
bob.setx(bob.xcor() - 5)
root = tk.Tk()
canvas = tk.Canvas(root, width=500, height=500)
canvas.pack()
wn = TurtleScreen(canvas)
bob = RawTurtle(wn, shape="turtle")
bob.penup()
topFrame = tk.Frame(root)
topFrame.pack()
middleFrame = tk.Frame(root)
middleFrame.pack()
bottomFrame = tk.Frame(root)
bottomFrame.pack()
tk.Button(topFrame, text="Up", fg="red", command=goUp).pack()
tk.Button(middleFrame, text="Left", fg="red", command=goLeft).pack(side=tk.LEFT)
tk.Button(middleFrame, text="Right", fg="red", command=goRight).pack(side=tk.RIGHT)
tk.Button(bottomFrame, text="Down", fg="red", command=goDown).pack()
wn.mainloop()

Related

Tkinter center Label in the GUI

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?

Modules and classes in Python for a desktop application

This is to be a desktop application for opening multiple small databases and running queries on them. So far I've written some code for opening forms as necessary. Is this a good way to do it? Also - the code shown opens two copies of each form - what am I doing wrong? It's my first attempt at Python and I'm a rudimentary programmer so simple answers would be of most help please. TIA (Python 3.9.6)
link_1.py
from tkinter import Tk
import link_2
root = Tk()
class ClassLink_1:
#if another function in the class is called, the __init__ function is run at start up
def __init__(self):
print("in link_1 __init__ instruction")
#the call_function function can be called at start up, or not, and will act accordingly
def call_function(self):
print("in call_function")
#the line below is run at start up whether or not another function in the class is called
print("in link_1")
root.withdraw() #hides the blank form at start up
#if __name__ == "__main__":
#the line below shows the link_2 form, whether or not the if __name__==__main__ condition is used as its condition
link_2.ClassLink_2(root).__init__(root)
#link_3.ClassLink_3(root).__init__(root)
#the line below runs call_function on start up to print text
ClassLink_1().call_function()
root.mainloop()
link_2.py
from tkinter import Tk, Button
from tkinter import * #for Toplevel
import link_3
root = Tk()
class ClassLink_2:
def __init__(self, master):
self.openNewWindow()
def openNewWindow(self):
newWindow = Toplevel(root) #creates a top level widget with the parent root (first parameter)
newWindow.title("Title opened from link_1")
newWindow.geometry("500x500")
label = Label(newWindow, text ="Opened from link_1").grid(row=1, column=1)
self.add_button = Button(newWindow, text="in ClassLink_2", command= self.do_add)
self.add_button.grid(row=3, column=1)
def do_add(self):
print("button pressed")
link_3.ClassLink_3(root).__init__(root)
root.withdraw() #hides the blank form at start up
link_3.py
from tkinter import Tk, Button
from tkinter import * #for Toplevel
root = Tk()
class ClassLink_3:
def __init__(self, master):
self.openNewWindow()
def openNewWindow(self):
newWindow = Toplevel(root) #creates a top level widget with the parent root (first parameter)
newWindow.title("Title opened from link_2")
newWindow.geometry("500x500")
label = Label(newWindow, text ="Opened from link_2").grid(row=1, column=1)
self.add_button = Button(newWindow, text="in ClassLink_3", command= self.do_add)
self.add_button.grid(row=3, column=1)
def do_add(self):
print("button pressed")
# link_4.ClassLink_4(root).__init__(root) this file has not yet been made
root.withdraw() #hides the blank form at start up
This is a proposed solution, can be expanded as needed. Constructive suggestions for improvement of the structure or code would be appreciated. TIA. I've left in the details in case they are of use to anyone.
link_1
from tkinter import Tk
import link_2
root = Tk()
class ClassLink_1:
def __init__(self):
print("in link_1 __init__ instruction")
root.withdraw() #hides the blank form at start up
link_2.ClassLink_2(root).openNewWindow(0)
root.mainloop()
link_2
from tkinter import Tk, Button
from tkinter import *
import link_3
root = Tk()
class ClassLink_2:
root.withdraw() #hides the blank form at start up
class_var_1 = 0
inst_var_1 = 0
def __init__(self, incoming_inst_var_1):
pass
def openNewWindow(self, inst_var_1_to_open):
newWindow = Toplevel(root)
newWindow.title("Title opened from link_1")
newWindow.geometry("500x500")
label = Label(newWindow, text ="Opened from link_1").grid(row=1, column=1)
self.add_button = Button(newWindow, text="in ClassLink_2", command= self.do_add)
self.add_button.grid(row=3, column=1)
self.add_button = Button(newWindow, text="increment class_var_1", command= self.inc_class_var_1)
self.add_button.grid(row=5, column=1)
self.inst_var_1 = inst_var_1_to_open
def do_add(self):
print("button pressed")
link_3.ClassLink_3(root).openNewWindow(0)
def inc_class_var_1(self):
ClassLink_2.class_var_1 += 2
self.inst_var_1 += 1
print("self.class_var_1 = " + (str)(self.class_var_1))
print("self.inst_var_1 = " + (str)(self.inst_var_1))
link_3
from tkinter import Tk, Button
from tkinter import *
from tkinter.ttk import Combobox
import tkinter.scrolledtext as tkscrolled
# import link_4 <filename of next form>
root = Tk()
class ClassLink_3:
class_var_1 = 0
inst_var_1 = 0
# ------------------------------- START CLASS CONTROLS -----------------------------
root.withdraw()
def __init__(self, incoming_inst_var_1):
pass
def openNewWindow(self, inst_var_1_to_open):
new_window = Toplevel(root)
self.widget_factory(new_window)
self.inst_var_1 = inst_var_1_to_open
def do_add(self):
print("button pressed")
# link_4.ClassLink_4(root).openNewWindow(0) # <filename of next form>
# ---------------------------------- END CLASS CONTROLS -----------------------------
# -------------------------------------- START CALCS --------------------------------------
def inc_class_var_1(self):
ClassLink_3.class_var_1 += 2
self.inst_var_1 += 1
print("self.class_var_1 = " + (str)(self.class_var_1))
print("self.inst_var_1 = " + (str)(self.inst_var_1))
# ---------------------------------------- END CALCS --------------------------------------
# ---------------------------------------- START FACTORY SHOPS-----------------------------------------
def widget_factory(self, new_window):
self.shop_window(new_window)
self.shop_labels(new_window)
self.shop_buttons(new_window)
self.shop_menu(new_window)
self.shop_listbox(new_window)
self.shop_combobox(new_window)
self.shop_radiobuttons(new_window)
self.shop_checkbuttons(new_window)
self.shop_entries(new_window)
self.shop_canvas(new_window)
self.shop_scale(new_window)
self.shop_scrollbars(new_window)
self.shop_textbox(new_window)
self.shop_menu(new_window)
pass
# ------------------------
def shop_window(self, new_window):
new_window.title("Title opened from link_2")
new_window.geometry("800x900")
def shop_labels(self, new_window):
self.label_1 = Label(new_window, text ="Opened from link_2").grid(row=1, column=1)
def shop_buttons(self, new_window):
self.button_1 = Button(new_window, text="in ClassLink_3", command= self.do_add)
self.button_1.grid(row=3, column=1)
self.button_2 = Button(new_window, text="increment class_var_1", command= self.inc_class_var_1)
self.button_2.grid(row=5, column=1)
def shop_listbox(self, new_window):
data=("one", "two", "three", "four")
self.listbox_1 = Listbox(new_window, height=5, selectmode='multiple')
for num in data:
self.listbox_1.insert(END,num)
self.listbox_1.grid(row=7, column=1)
def shop_combobox(self, new_window):
data=("one", "two", "three", "four")
self.combobox_1 = Combobox(new_window, values=data)
self.combobox_1.grid(row=8, column=3)
def shop_radiobuttons(self, new_window):
var_1 = IntVar()
var_1.set(1)
self.rad_btn_1 = Radiobutton(new_window, text="male", variable=var_1, value=1)
self.rad_btn_2 = Radiobutton(new_window, text="female", variable=var_1, value=2)
self.rad_btn_1.grid(row=9, column=1)
self.rad_btn_2.grid(row=9, column=2)
def shop_checkbuttons(self, new_window):
var_1 = IntVar()
var_2 = IntVar()
self.checkbtn_1 = Checkbutton(new_window, text = "Cricket", variable = var_1)
self.checkbtn_2 = Checkbutton(new_window, text = "Tennis", variable = var_2)
self.checkbtn_1.grid(row=10, column=1)
self.checkbtn_2.grid(row=10, column=2)
def shop_entries(self, new_window):
self.entry_1 = Entry(new_window, width = 20)
self.entry_1.insert(0,'Username')
self.entry_1.grid(row= 11, column=2)
self.entry_2 = Entry(new_window, width = 15)
self.entry_2.insert(0,'password')
self.entry_2.grid(row= 12, column=2)
#might want to place on a frame, see example https://coderslegacy.com/python/list-of-tkinter-widgets/
def shop_canvas(self, new_window):
canvas = Canvas(new_window, bg= 'white', width = 260,height = 260) #this is the background for the figure
# left and top of figure is from [x from left, y from top] of canvas right and bottom of figure from [x from left, y from top] of canvas
coordinates = 20, 50, 210, 230
arc = canvas.create_arc(coordinates, start=0, extent=250, fill="blue") #start is from E, extent is in degrees CCW
arc = canvas.create_arc(coordinates, start=250, extent=50, fill="red")
arc = canvas.create_arc(coordinates, start=300, extent=60, fill="yellow")
canvas.grid(row=2, column=1)
def shop_scale(self, new_window):
self.scale_1 = Scale(new_window, from_=0, to=10, orient=VERTICAL)
self.scale_1.grid(row=15, column=2)
self.scale_2 = Scale(new_window, from_=0, to=10, orient = HORIZONTAL)
self.scale_2.grid(row=15, column=3)
def shop_scrollbars(self, new_window):
self.scroll_vert = Scrollbar(new_window)
self.scroll_vert.grid(row=19, column=3)
self.listbox_3 = Listbox(new_window, yscrollcommand = self.scroll_vert.set )
for line in range(1, 100):
self.listbox_3.insert(END, "Number " + str(line))
self.listbox_3.grid(row=19 , column=2)
self.scroll_vert.config(command = self.listbox_3.yview)
def shop_textbox(self, new_window):
#make a frame with parent new_window
self.frame_textbox_1 = Frame(new_window)
self.frame_textbox_1.grid(row=1, column=5)
#make the textbox with parent frame
self.textbox_1 = Text(self.frame_textbox_1)
self.textbox_1.config(wrap=NONE, width=15, height=8) #width, height are characters x rows permitted wrap values should be WORD CHAR, or NONE
#make the X scrollbar with parent frame
self.scroll_text_horiz = Scrollbar(self.frame_textbox_1, orient="horizontal")
self.scroll_text_horiz.config(command = self.textbox_1.xview)
#make the Y scrollbar with parent frame
self.scroll_text_vert = Scrollbar(self.frame_textbox_1, orient="vertical")
self.scroll_text_vert.config(command = self.textbox_1.yview)
#pack the scrollbars before the texbox to allow them to fill the frame width and height
self.scroll_text_horiz.pack(side=BOTTOM, fill=X)
self.scroll_text_vert.pack(side=RIGHT, fill=Y)
self.textbox_1.pack(fill="y")
#connect the scrollbars to the textbox
self.textbox_1["xscrollcommand"] = self.scroll_text_horiz.set
self.textbox_1["yscrollcommand"] = self.scroll_text_vert.set
message = "the quick brown fox"
self.textbox_1.insert(1.1, message)
# ----------------------------------------------
def shop_menu(self, new_window):
print("in shop menu1")
menubar = Menu(new_window)
print("in shop_menu2")
file = Menu(menubar, tearoff=0)
file.add_command(label="New")
file.add_command(label="Open")
file.add_command(label="Save")
file.add_command(label="Save as...")
file.add_command(label="Close")
file.add_separator()
file.add_command(label="Exit", command=new_window.quit)
menubar.add_cascade(label="File", menu=file)
edit = Menu(menubar, tearoff=0)
edit.add_command(label="Undo")
edit.add_separator()
edit.add_command(label="Cut")
edit.add_command(label="Copy")
edit.add_command(label="Paste")
edit.add_command(label="Delete")
edit.add_command(label="Select All")
menubar.add_cascade(label="Edit", menu=edit)
help = Menu(menubar, tearoff=0)
help.add_command(label="About")
menubar.add_cascade(label="Help", menu=help)
new_window.config(menu=menubar)
print("in shop menu3")
# --------------------------------------- END FACTORY SHOPS---------------------------------------

How to get the buttons to the left side?

I am trying to create the buttons using tkinter.
Here is my code
import tkinter as tk
def pressed():
print("button pressed!")
def create_layout(frame):
frame.pack(fill=None,expand=True)
mycolor = '#%02x%02x%02x' % (250, 250, 210)
root.configure(bg=mycolor)
bottomframe = tk.Frame(root)
bottomframe.pack( side = tk.LEFT )
button1 = tk.Button(frame, text="Button1", fg="black",command=pressed,anchor="w")
button1.pack( side = tk.LEFT)
button2 =tk.Button(frame, text="Button2", fg="black",command=pressed,anchor="w")
button2.pack( side = tk.LEFT )
root = tk.Tk()
root.geometry("250x150")
frame = tk.Frame(root)
create_layout(frame)
root.mainloop()
I have specified the anchor="w", and side="LEFT", but it does not seem to be work.
Output of the code:
Changing frame.pack(fill=None,expand=True) to frame.pack(fill=None,expand=True, anchor="w") will align the buttons to the left side.

Python canvas colour change by button

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()

Secret tkinter widget?

I got this problem. when I write secretframe() I get a empty box any ideas to fix this? Also how can I put a little space between the 2 frames.
I'm new to tkinter and any tips is gladly appreciated.
import tkinter as tk
import time
import math
##----------Functions
root = tk.Tk()
def Pi():
pi = math.pi
x = list(str(pi))
map(int,x)
print(math.pi)
def Unfinished():
print("This Button is not finished")
def secretframe(frame):
secrett = tk.Toplevel()
sframe = tk.Frame(secrett, height="300", width="300", bg="PeachPuff")
sLabel = tk.Label(sframe, text="Secret")
sframe.grid
sLabel.grid
##Defining
##Frames
frame = tk.Frame(root, height="300", width="300", bg="Black")
Mframe = tk.Frame(root, height="300", width="300", bg="White")
##WIdgets
Label = tk.Label(frame, text="R1p windows", bg="Black", fg="White")
Label2 = tk.Label(Mframe, text="Math magic", bg="White", fg="Black")
Knapp = tk.Button(frame, text="ok(ADMIN)", fg="White", bg="Black", font="monospace")
PIKnapp = tk.Button(Mframe, text="Pi(WIP)(UNFINISHED)", bg="White", fg="Black", font="Times")
##Config and bindings
Knapp.config(command=Unfinished)
PIKnapp.config(command=Pi)
##Packing
## Frame 1
Label.grid()
frame.grid()
Knapp.grid()
## Frame 2
Label2.grid()
Mframe.grid()
PIKnapp.grid()
You've forgotten the brackets. Try:
sframe.grid ()
sLabel.grid ()

Categories

Resources