Jakey Snakey
Jakey Snakey

Reputation: 95

Python turtle program works in IDLE, not otherwise

I have created a simple button program using turtle in Python. It is most likely very sloppy but works perfectly in IDLE. However, when trying to load it without IDLE it just draws the two buttons and then quits the program. I've looked over the code without any success on finding the cause.

Here's where I think the issue is (the last few lines):

def main():
    onscreenclick(Button.clicked,1)

main()

However I am not entirely sure. Here is the full program just in case.

from turtle import *
bgcolor('skyblue')
penup()
left(90)
speed(0)
hideturtle()
buttonlist = []

class Button:
  x_click = 0
  y_click = 0
  def __init__(self, x, y, size, color, text, fontsize, fixvalue):
    self.x = x
    self.y = y
    self.size = size
    self.color = color
    self.text = text
    self.fontsize = fontsize
    self.fixvalue = fixvalue
  def showButton(self):
    goto(self.x , self.y)
    pendown()
    fillcolor(self.color)
    begin_fill()
    for i in range(4):
      forward(self.size)
      right(90)
    end_fill()
    penup()
    goto((self.x+self.size/2),self.y+self.fixvalue)
    right(90)
    write(self.text, move=False, align="center", font=("Arial", self.fontsize, "normal"))
    left(90)
  def hideButton(self):
    goto(self.x, self.y)
    fillcolor('skyblue')
    pencolor('skyblue')
    pendown()
    begin_fill()
    for i in range(4):
      forward(self.size)
      right(90)
    end_fill()
    penup()
    pencolor('black')
  def checkClick(self):
    if self.x < Button.x_click:
      if Button.x_click < (self.x+self.size):
        if self.y < Button.y_click:
          if Button.y_click < (self.y+self.size):
            return 1

  def clicked(x, y):
    Button.x_click = x
    Button.y_click = y

    if home_1.checkClick() == 1:
      home_1.hideButton()
    if home_2.checkClick() == 1:
      home_2.hideButton()

home_1 = Button(10,10,100,'red','←',45,20)
home_2 = Button(-50,-50,50,'blue','Hello!',10,15)
Button.showButton(home_1)
Button.showButton(home_2)

def main():
    onscreenclick(Button.clicked,1)

main()

I hope there is a solution.

Cheers.

Upvotes: 4

Views: 1245

Answers (2)

Terry Jan Reedy
Terry Jan Reedy

Reputation: 19219

turtle is based on tkinter, which is based on the tcl/tk GUI framework. Turtle's mainloop ultimately calls the tcl event-handler mainloop, which repeatedly calls tcl's update() function, which handles pending events and update the screen. Tcl's mainloop keeps control until it is explicitly exited, such as by closing the turtle window.

IDLE aids turtle and tkinter development and learning by periodically calling tcl's update without blocking, so that one can (temporarily) omit calling mainloop and interact with the screen or screens one is working on by entering commands in the IDLE Shell. But mainloop needs to be added back when running outside of IDLE.

Upvotes: 0

Mahi
Mahi

Reputation: 21969

You're right that the issue lies in the main() function, try adding a turtle.mainloop() call to the end:

def main():
    onscreenclick(Button.clicked,1)
    mainloop()

main()

If that doesn't work for you, you can also try the turtle.done() function, although I recommend you to try mainloop() first:

def main():
    onscreenclick(Button.clicked,1)
    done()

main()

Upvotes: 3

Related Questions