使用海龟模块 exitonclick() [英] Using turtle module exitonclick()

查看:105
本文介绍了使用海龟模块 exitonclick()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码应该在第一部分之后关闭turtle.screen,然后启动另一个屏幕并执行第二部分.但它没有按预期工作.

My code should close the turtle.screen after first part then start another screen and do the second part. but there it is not working as intend.

import turtle

ws = turtle.Screen()
tod_1 = turtle.Turtle()
tod_1.color("red", "green")
tod_1.begin_fill()
for i in range(3):
    tod_1.forward(50)
    tod_1.left(360 / 3)
tod_1.end_fill()
ws.exitonclick()

input("go'press any thing' ")

ws = turtle.Screen()
tod_2 = turtle.Turtle()
tod_2.color("red", "green")
tod_2.begin_fill()
for i in range(6):
    tod_2.forward(50)
    tod_2.left(360 / 6)
tod_2.end_fill()
ws.exitonclick()

第一部分工作正常,但我在 input() 之后得到了这个:

the first part works fine but I get this after the input():

go'press any thing' 
Traceback (most recent call last):
  File "test2.py", line 16, in <module>
    tod_2 = turtle.Turtle()
  File "C:\Users\itt\AppData\Local\Programs\Python\Python36-32\lib\turtle.py", line 3816, in __init__
    visible=visible)
  File "C:\Users\itt\AppData\Local\Programs\Python\Python36-32\lib\turtle.py", line 2557, in __init__
    self._update()
  File "C:\Users\itt\AppData\Local\Programs\Python\Python36-32\lib\turtle.py", line 2660, in _update
    self._update_data()
  File "C:\Users\itt\AppData\Local\Programs\Python\Python36-32\lib\turtle.py", line 2646, in _update_data
    self.screen._incrementudc()
  File "C:\Users\itt\AppData\Local\Programs\Python\Python36-32\lib\turtle.py", line 1292, in _incrementudc
    raise Terminator
turtle.Terminator

我尝试使用以下方法清除所有变量:

I tried to clear all variables using:

import sys
sys.modules[__name__].__dict__.clear()

然后再次导入turtle并执行秒.部分,但没有成功.

then import turtle again and do the sec. part, but without success.

推荐答案

似乎在导入 turtle 时它会创建许多对象,而 exitonclick() 将它们全部删除- 不仅仅是 Screen().exitonclick() 是为了结束程序而创建的.

It seems that when turtle is imported it creates many objects and exitonclick() removes all of them - not only Screen(). exitonclick() was created to end program.

但是您可以使用 oscreenclick(function_name) 将功能分配给鼠标单击,这将清除屏幕并绘制下一个对象.onscreenclick 使用两个参数执行函数 - 单击位置 - 所以函数必须接收此信息.

But you can use oscreenclick(function_name) to assign function to mouse click which will clear screen and draw next object. onscreenclick execute function with two arguments - position of click - so function has to receive this information.

import turtle

# --- functions ---

def second(x, y): 
    # clear screen
    tod.reset()

    tod.color("red", "green")
    tod.begin_fill()
    for i in range(6):
        tod.forward(50)
        tod.left(360 / 6)
        tod.end_fill()

    # run another function on click
    #turtle.onscreenclick(third)

    # end program on click 
    turtle.exitonclick()

# --- main ---

tod = turtle.Turtle()

tod.color("red", "green")
tod.begin_fill()
for i in range(3):
    tod.forward(50)
    tod.left(360 / 3)
    tod.end_fill()

# assign function to click on screen
turtle.onscreenclick(second)

# you need it to - it checks if you clicked (and does othere things)
turtle.mainloop()

<小时>

如果您必须删除窗口并再次显示,则可以使用 tod._screen._root 访问使用 tkinter<的主窗口/code>,你可以隐藏/显示它


if you have to remove window and show again than you can use tod._screen._root to get access to main window which use tkinter, and you can hide/show it

tod._screen._root.iconify()   # hide
input("Press Enter: ")
tod._screen._root.deiconify() # show again

工作示例:

#!/usr/bin/env python3

import turtle

# --- functions ---

def stop(callback):

    #tod._screen._root.attributes("-topmost", False)

    tod._screen._root.iconify()
    # upper Y in text means that it will be default answer if you press only Enter
    answer = input("Show more images? [Y/n]: ").strip().lower()
    if not answer: # empty string treat as `Y`
        answer = 'y'
    tod._screen._root.deiconify()

    # problem with moving window above other windows
    #tod._screen._root.lift()
    tod._screen._root.attributes("-topmost", True)
    #tod._screen._root.update()

    if answer == 'y':
        callback()
    else:
        #turtle.exitonclick()
        # or
        turtle.bye()

def first(x=0, y=0):
    tod.color("red", "green")
    tod.begin_fill()
    for i in range(3):
        tod.forward(50)
        tod.left(360 / 3)
        tod.end_fill()

    # assign function to click on screen
    turtle.onscreenclick(lambda x,y:stop(second))

def second(x=0, y=0):
    # clear screen
    tod.reset()

    tod.color("red", "green")
    tod.begin_fill()
    for i in range(6):
        tod.forward(50)
        tod.left(360 / 6)
        tod.end_fill()

    # assign function to click on screen
    turtle.onscreenclick(lambda x,y:stop(third))

def third(x=0, y=0):
    # clear screen
    tod.reset()

    tod.color("red", "green")
    tod.begin_fill()
    for i in range(12):
        tod.forward(50)
        tod.left(360 / 12)
        tod.end_fill()

    # end program on click
    turtle.exitonclick()

# --- main ---

tod = turtle.Turtle()

first()

# you need it to - it checks if you clicked (and does othere things)
turtle.mainloop()

但是你可以使用 tkinter 和它的消息框来代替 input()

But instead of input() you can use tkinter and its messageboxes

answer = tkinter.messagebox.askyesno('More?', "Show more images?")

工作示例:

#!/usr/bin/env python3

import turtle
import tkinter.messagebox

# --- functions ---

def stop(callback):

    answer = tkinter.messagebox.askyesno('More?', "Show more images?")
    print('answer:', answer)

    if answer:
        callback()
    else:
        #turtle.exitonclick()
        # or
        turtle.bye()

def first(x=0, y=0):
    tod.color("red", "green")
    tod.begin_fill()
    for i in range(3):
        tod.forward(50)
        tod.left(360 / 3)
        tod.end_fill()

    # assign function to click on screen
    turtle.onscreenclick(lambda x,y:stop(second))

def second(x=0, y=0):
    # clear screen
    tod.reset()

    tod.color("red", "green")
    tod.begin_fill()
    for i in range(6):
        tod.forward(50)
        tod.left(360 / 6)
        tod.end_fill()

    # assign function to click on screen
    turtle.onscreenclick(lambda x,y:stop(third))

def third(x=0, y=0):
    # clear screen
    tod.reset()

    tod.color("red", "green")
    tod.begin_fill()
    for i in range(12):
        tod.forward(50)
        tod.left(360 / 12)
        tod.end_fill()

    # end program on click
    turtle.exitonclick()

# --- main ---

tod = turtle.Turtle()

first()

# you need it to - it checks if you clicked (and does othere things)
turtle.mainloop()

<小时>

我检查了turtle的源代码,看来你可以设置


I checked source code of turtle and it seems that you can set

turtle.TurtleScreen._RUNNING = True

exitonclick()

在有和没有turtle.TurtleScreen._RUNNING = True

import turtle

turtle.goto(0,50)
turtle.exitonclick()

turtle.TurtleScreen._RUNNING = True

turtle.goto(50,150)
turtle.exitonclick()

turtle.TurtleScreen._RUNNING = True

但也许对于更复杂的代码它不起作用,因为 exitonclick() 做其他事情 - 由 exitonclick()

But maybe with more complex code it will not work because exitonclick() does other things - oryginal function which is executed by exitonclick()

def _destroy(self):
    root = self._root
    if root is _Screen._root:
        Turtle._pen = None
        Turtle._screen = None
        _Screen._root = None
        _Screen._canvas = None
    TurtleScreen._RUNNING = False
    root.destroy()

这篇关于使用海龟模块 exitonclick()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆