Turtle screen closes almost immediately after opening - python

I writed some code from a python book and the book shows that if you run the code there will be no problem
but when I ran the code there was a problem
This is my code:
import turtle
import time
turtle.pensize(5)
turtle.bgcolor("black")
turtle.pencolor("white")
turtle.turtlesize(2,2,2)
def ileri():
turtle.fd(5)
def geri():
turtle.backward(5)
def sag():
turtle.right(90)
turtle.fd(5)
turtle.left(90)
def sol():
turtle.left(90)
turtle.fd(5)
turtle.right(90)
def sagdon():
turtle.right(10)
def soldon():
turtle.left(10)
def siyah():
turtle.pencolor("black")
def yesil():
turtle.pencolor("green")
def acikyesil():
turtle.pencolor("lightgreen")
def mavi():
turtle.pencolor("blue")
def acikmavi():
turtle.pencolor("lightblue")
def sari():
turtle.pencolor("yellow")
def kirmizigul():
turtle.pencolor("red")
turtle.onkeypress(ileri, "w" or "Up")
turtle.onkeypress(geri, "s" or "Down")
turtle.onkeypress(sag, "d")
turtle.onkeypress(sol, "a")
turtle.onkeypress(sagdon, "Right")
turtle.onkeypress(soldon, "Left")
turtle.onkeypress(siyah, "0")
turtle.onkeypress(yesil, "1")
turtle.onkeypress(acikyesil, "2")
turtle.onkeypress(mavi, "3")
turtle.onkeypress(acikmavi, "4")
turtle.onkeypress(sari, "5")
turtle.onkeypress(kirmizigul, "6")
turtle.listen()
when I try to run this game every hecking time a screen opens for like 0.1 second and closes
if you try to help it will be so good for me
I was expecting the screen was going to be remain open because it was in the books image but I was not expecting to see the screen for just 0.1 seconds

Use turtle.done() at the end of your code and the window will stay until you close it yourself.

The official python wiki page for turtle clearly states that:
(turtle.mainloop) Must be the last statement in a turtle graphics program. Must not be used if a script is run from within IDLE in -n mode (No subprocess) - for interactive use of turtle graphics.
Since your program lacks a call to the mainloop function, it closes as soon as it is runs. All you have to do is add a
turtle.mainloop()
turtle.done()
at the end of your program.
I hope this helps :)

i believe this is what you tried to do all you had to do is import screen and set the screen setup and update it:
import turtle
from turtle import Screen
import time
turtle.pensize(5)
turtle.bgcolor("black")
turtle.pencolor("white")
turtle.turtlesize(2,2,2)
screen= Screen()
screen.setup(600,600)
def ileri():
turtle.fd(5)
def geri():
turtle.backward(5)
def sag():
turtle.right(90)
turtle.fd(5)
turtle.left(90)
def sol():
turtle.left(90)
turtle.fd(5)
turtle.right(90)
def sagdon():
turtle.right(10)
def soldon():
turtle.left(10)
def siyah():
turtle.pencolor("black")
def yesil():
turtle.pencolor("green")
def acikyesil():
turtle.pencolor("lightgreen")
def mavi():
turtle.pencolor("blue")
def acikmavi():
turtle.pencolor("lightblue")
def sari():
turtle.pencolor("yellow")
def kirmizigul():
turtle.pencolor("red")
while(True):
screen.update()
time.sleep(0.07)
turtle.onkeypress(ileri, "w" or "Up")
turtle.onkeypress(geri, "s" or "Down")
turtle.onkeypress(sag, "d")
turtle.onkeypress(sol, "a")
turtle.onkeypress(sagdon, "Right")
turtle.onkeypress(soldon, "Left")
turtle.onkeypress(siyah, "0")
turtle.onkeypress(yesil, "1")
turtle.onkeypress(acikyesil, "2")
turtle.onkeypress(mavi, "3")
turtle.onkeypress(acikmavi, "4")
turtle.onkeypress(sari, "5")
turtle.onkeypress(kirmizigul, "6")
turtle.listen()
screen.exitonclick()
hope it was usefull to you and goodluck.

Related

Drawing Basic Animations in Python

Hello I am trying to create something like this box with controllable dots
I need to be able to move and interact with the dots. I have tried turtle and pyglet, but neither of them seem to do what I want them to do.
Turtle is letting me create dots but it doesnt seem to play well with oop. I'm a super noob at python oop so maybe I'm just doing it wrong but I can't seem to make an turtle object that I can actually use how I want. I would ideally be able to use my own methods built off of the turtle methods, and create and call on data unique to each turtle.
import turtle
import time
import random
wn = turtle.Screen()
wn.title("simulation")
wn.bgcolor("tan")
def rng(whatisrandom):
match whatisrandom:
case 'coords': return(random.randint(-400,400) , random.randint(-400,400))
case 'heading':return(random.randint(0,359))
case 'forward':return(random.randint(0,50))
class bug():
def __init__(self) -> None:
self = turtle.Turtle(shape = "circle",visible=False)
self.speed(0)
self.penup()
self.setpos(rng('coords'))
self.showturtle()
self.speed(1)
self.forward(20)
def move(self):
self.setheading(rng('heading'))
self.forward(rng('forward'))
bug1 = bug()
bug1.move()
wn.mainloop()
this is the error message.
self.setheading(rng('heading'))
^^^^^^^^^^^^
AttributeError: 'bug' object has no attribute 'heading'
I ultimately want to animate these little bugs with neural nets and train them to do different movements, and eventually interact with each other.
This appears to be a misunderstanding of how to subclass an object in Python. Let's rearrange things a bit:
from turtle import Screen, Turtle
from random import randint
class Bug(Turtle):
def __init__(self):
super().__init__(shape='circle', visible=False)
self.speed('fastest')
self.penup()
self.setposition(Bug.rng('coords'))
self.showturtle()
self.speed('slowest')
self.forward(20)
def move(self):
self.setheading(Bug.rng('heading'))
self.forward(Bug.rng('forward'))
#staticmethod
def rng(whatisrandom):
if whatisrandom == 'coords':
return randint(-400, 400), randint(-400, 400)
if whatisrandom == 'heading':
return randint(0, 359)
if whatisrandom == 'forward':
return randint(0, 50)
return None
screen = Screen()
screen.title("Simulation")
screen.bgcolor('tan')
bug1 = Bug()
bug1.move()
screen.mainloop()
I don't have an issue with your match statement, I'm just unfamiliar with it and haven't updated my Python sufficiently!

How to make text as a sprite in turtle?

For example I want to do something like this:
textSprite=new object(text("Hello"))
turtle.display(textSprite)
-Then do
time.sleep(10)
textSprite.hide()
-Or
while i<100:
time.sleep(10)
textsprite.size=i
-Or
textSprite.x=10
textSprite.y=100
time.sleep(100)
textSprite.x=20
textSprite.y=200
I tried searching google but I got no answers.
update: some question changes have been made
Since Python is generally object-oriented, and turtle specifically is, you can create your own TextSprite class using turtle as underpinning:
from turtle import Turtle
class TextSprite(Turtle):
DEFUALT_FONT = ('Arial', 18, 'normal')
def __init__(self, text):
super().__init__(visible=False)
self.text = text
self.font = self.DEFUALT_FONT
self.penup()
def setfont(self, font):
self.font = font
def showtext(self):
self.write(self.text, align='center', font=self.font)
def hidetext(self):
self.clear()
if __name__ == "__main__":
from turtle import Screen
screen = Screen()
sprite = TextSprite("Hello")
sprite.goto(100, 100)
sprite.color('blue')
sprite.setfont(('Times Roman', 24, 'bold'))
sprite.showtext()
screen.ontimer(sprite.hidetext, 10_000) # ten seconds
screen.exitonclick()

How to use turtle.onclick with an object from a class?

I want to make a class for turtle buttons and have a field to be the turtle
and here is the code I wrote:
class button:
def __init__(self,color,x,y):
self.turtle=turtle.Turtle()
self.turtle.penup()
self.turtle.shape("square")
self.turtle.color(color)
self.turtle.speed(0)
self.turtle.goto(x,y)
Now I want to use the onclick to a button instance, so how do I do that is it something like this?
def click(self,x,y):
print ("hello world")
self.turtle.onclick()
I'm not that good at classes btw so I just want something simple.
Here's how to bind the class' click() method to mouse-click events. See the documentation for the turtle.onclick() method.
import turtle
SCREENWIDTH = 640
SCREENHEIGHT = 480
class Button:
def __init__(self,color,x,y):
self.turtle = turtle.Turtle()
self.turtle.penup()
self.turtle.shape("square")
self.turtle.color(color)
self.turtle.speed(0)
self.turtle.goto(x,y)
self.turtle.onclick(self.click) # Bind mouse-click event to method.
def click(self, x, y):
print ("hello world")
if __name__ == "__main__":
mainscreen = turtle.Screen()
mainscreen.mode("standard")
mainscreen.setup(SCREENWIDTH, SCREENHEIGHT)
Button('red', 0, 0)
turtle.mainloop()
P.S. I strongly suggest you read and start following the coding suggestions in the PEP 8 - Style Guide for Python Code. It will make your code easier to read and understand.

Python 3.7.2 Turtle source folder-specific error message

I have installed Python 3.7.2 in Windows 7. When I write turtle code and save it in the Python folder, it runs without errors. If I save it in another folder, it returns this error:
NameError: name dot is not defined.
Here is my code:
from tkinter import *
from tkinter import ttk
from turtle import *
def triangle():
fd(200);left(135);fd(150);goto(0,0)
def rectangle():
lt(180);fd(250);lt(90);fd(125);lt(90);fd(250);lt(90);fd(125)
def square():
fd(250);rt(90);fd(250);rt(90);fd(250);rt(90);fd(250)
def grdk():
circle(75)
window=Tk()
window.title('GeoFigs')
window.geometry('250x200')
label=Label(window,text='Choose one figure',font='Aharoni -22 bold')
label.pack()
sekunga=ttk.Button(window,text='TRIANGLE',command=triangle)
sekunga.pack()
chor=ttk.Button(window,text='RECTANGLE',command=rectangle)
chor.pack()
kv=ttk.Button(window,text='SQUARE',command=square)
kv.pack()
grd=ttk.Button(window,text='CIRCLE',command=grdk)
grd.pack()
mainloop()
I'm not sure if it has anything to do with your "NameError: name dot is not defined" issue but I wouldn't begin to debug a turtle program set up like this one. Turtle is designed to work in either standalone (turtle alone) or embedded (turtle and tkinter) mode but you have it embedded in standalone mode which risks creating two Tk roots and other issues. Below is a rework of your turtle code in embedded mode:
from tkinter import *
from turtle import ScrolledCanvas, TurtleScreen, RawTurtle
def triangle():
turtle.forward(200)
turtle.left(135)
turtle.forward(150)
turtle.home()
def rectangle():
turtle.left(90)
for _ in range(2):
turtle.left(90)
turtle.forward(250)
turtle.left(90)
turtle.forward(125)
def square():
for _ in range(4):
turtle.forward(200)
turtle.right(90)
def circle():
turtle.circle(75)
window = Tk()
window.title('Graphics')
window.geometry('640x480+300+0')
figures = Toplevel(window)
figures.title('Figures')
figures.geometry('250x150')
Label(figures, text='Choose one figure').pack()
Button(figures, text='TRIANGLE', command=triangle).pack()
Button(figures, text='RECTANGLE', command=rectangle).pack()
Button(figures, text='SQUARE', command=square).pack()
Button(figures, text='CIRCLE', command=circle).pack()
canvas = ScrolledCanvas(window)
canvas.pack(fill="both", expand=True)
screen = TurtleScreen(canvas)
screen.screensize(640, 480)
turtle = RawTurtle(screen)
screen.mainloop()
Try this out and if the "NameError: name dot is not defined" persists, provide us a full error backtrace as an edit to your original question.

Python win32api.SetCursorPos dual screen issue

I am trying to create simple program which will click to specific coordinates every x seconds based on your choose if you need to click on Left screen or Right screen. My issue here is that win32api.SetCursorPos which is moving with my cursor is not moving to the secondary screen (right in my case). It stays in the main screen.
And I am having one more issue with my code, when Exit button inside GUI is pressed, window will close however program is still running in background. I am using self.Destroy() function to kill all process.
Thank you for your advice.
Here is my code:
import time
import pyautogui
import wx
import threading
import sys
import win32api
class bucky(wx.Frame):
def __init__(self,parent,id):
self.positionx = ""
self.positiony = ""
wx.Frame.__init__(self,parent,id,'AutoClick 2.0', size=(300,200))
panel=wx.Panel(self)
self.buttonpos=wx.Button(panel,label="Left Screen",pos=(30,10),size=(80,40))
self.buttonpos2=wx.Button(panel,label="Right Screen",pos=(180,10),size=(80,40))
self.button=wx.Button(panel,label="Start",pos=(120,90),size=(60,30))
self.button2=wx.Button(panel,wx.ID_EXIT,label="Exit",pos=(120,120),size=(60,30))
self.Bind(wx.EVT_BUTTON, self.action, self.button)
self.Bind(wx.EVT_BUTTON, self.closebutton, self.button2)
self.Bind(wx.EVT_BUTTON, self.position, self.buttonpos)
self.Bind(wx.EVT_BUTTON, self.position, self.buttonpos2)
self.Bind(wx.EVT_CLOSE, self.closewindow)
def position(self, event):
label = event.GetEventObject().GetLabel()
if label == "Left Screen":
self.positionx = 1640
self.positiony = 183
self.buttonpos.Disable()
self.buttonpos2.Enable()
elif label == "Right Screen":
self.positionx = 3308
self.positiony= 186
self.buttonpos.Enable()
self.buttonpos2.Disable()
def closebutton(self,event):
self.Destroy()
def closewindow(self,event):
self.Destroy()
def action(self,event):
self.button.Disable()
def callback():
while 1:
pos = pyautogui.position()
time.sleep(10)
pos1 = pyautogui.position()
if (pos1[0] == pos[0]) and (pos1[1] == pos[1]):
win32api.SetCursorPos((self.positionx, self.positiony))
pyautogui.click()
else:
pass
t = threading.Thread(target=callback)
t.start()
if __name__=='__main__':
app=wx.PySimpleApp()
frame=bucky(parent=None,id=1)
frame.Show()
app.MainLoop()
EDIT: Problem have been solved. Thank you for help.
Looking at this reddit post, I think the x coordinates for the secondary monitor are simply added to the resolution of the primary monitor (ex if you had two 1920x1080 monitors, the middle of the second monitor will be at 2880,520)
Try using (win32api.GetSystemMetrics(MONITOR_NUMBER) to see how the differences are represented.

Categories