【问题标题】:Python using turtle buttonPython使用乌龟按钮
【发布时间】:2023-08-18 12:00:01
【问题描述】:

我正在尝试在 python 中实现 Simon Says 的家庭作业。我正在尝试使用海龟库(要求)来做到这一点。

但是,我遇到了一个绊脚石,虽然我可以让屏幕注册点击事件(目前只是打印 x,y 坐标),但我无法让它等待点击事件。

具体来说,我打算在屏幕上设置一些区域,当他们在该位置单击时,就好像他们单击了按钮一样。屏幕清除和游戏做任何事情。

然而,在尝试获得一个工作“按钮”的实验中,它所做的只是设置它以便打印 x、y 坐标,但程序的其余部分完成。没有等待用户点击任何东西。我尝试了一种阻塞方法...

while clicked == False:
    pass

while clicked == False:
    time.sleep(1)

但这两种方法都会挂起程序,直到我手动中断,然后它会打印点击次数。

我是否在某处遗漏了一个选项?

【问题讨论】:

  • 你没有检查按钮按下吗?
  • 据我所知,Turtle 没有按钮。我试图模仿这种效果。如果有乌龟按钮,我很想知道。
  • 我从来没有用过海龟,但是有一个方法turtle.onrelease(fun, btn=1, add=None)我很确定如果你用这个你可以做一个按钮,只需检查x,y坐标?
  • 那调用附加函数是的。但程序不会等待。假设我有 2 个按钮。程序希望我推动其中一个。我会执行 'turtle.onrelease'、'turtle.onclick' 或任何它会调用该函数的方法,但由于预期的变量为空,因此程序已经崩溃,因为它将它设置为使用该函数然后继续。跨度>
  • 啊,这是线程问题吗?对不起,如果我解释错了

标签: python button turtle-graphics


【解决方案1】:

海龟没有按钮,但它们有点击回调。 此外,您应该使用onclick 用于Screen 来检测一般点击,并使用onclick 用于turtle 来检测海龟中的点击。例如,您可以使用动态形状制作 4 个不同颜色的 BIG 海龟。

另外,turtle 是基于 Tk 的,所以你必须注意 mainloop() 之类的东西

以下程序为 Python 2.7.5 提供了一些提示。

import turtle as t
from random import randint

class MyTurtle(t.Turtle) :

    def __init__(self,**args) :
        t.Turtle.__init__(self,**args)

    def mygoto(self,x,y) :
        t1.goto(x,y)
        print x,y

    def randonics(self,x,y) :
        self.left(randint(90,270))

def minegoto(x,y) :
    print x,y
    t1.goto(x,y)

wt=t.Screen()
t1=MyTurtle()
wt.register_shape("big",((0,0),(30,0),(30,30),(0,30)))
t1.shape("big")
wt.onclick(t1.mygoto,btn=1)
wt.onclick(minegoto,btn=2)
t1.onclick(t1.randonics,btn=3)
t1.goto(100,100)

t.mainloop()

【讨论】:

  • 这是我能够做到的。但是,我希望程序停止执行,一直保持到单击事件注册,找出单击的位置,并根据用户单击的位置执行一些代码。实际上是一个按钮。正如上面有人建议的那样,这可能需要线程化,但是程序只有一条路径(用户定义的路径),但只有一条。除非 t.mainloop() 做一些我想念的特别事情吗?
  • 您可以让注册到 onclick() 的函数测试 x,y 位置。如果它在某个区域内,你必须做任何你必须做的事情。我看不出你想要做什么和这段代码做什么之间的区别,乌龟位置的修改只是一个例子,当点击被 onclick() 捕获时你可以做任何事情,如果你真的可以启动一个线程需要它。
【解决方案2】:

因此,在广泛搜索之后,不一定有办法暂停执行 python 中的代码,同时使用 turtle 等待一些点击事件。也许在 Tk 中我可以做到这一点,但在海龟中不行。

但是,有一种方法可以解决这个问题。举个例子。一个方法在屏幕上设置假按钮,设置点击事件,然后终止。单击时的单击事件调用执行所需的下一个方法。因此,在单击按钮之前,实际代码不会执行任何操作,而是保留在内存中以供使用。

所以更具体地说。 1. 创建一个“按钮”。 2. 让您的程序正常运行,直到它需要等待点击事件。 3. 设置屏幕上的点击(或在海龟上),以便在点击“按钮”时运行下一部分代码。

特别说明。有问题的代码不能依赖于稍后在代码中等待点击事件。相反,单击会导致代码执行的下一部分。

【讨论】:

    【解决方案3】:

    您可以让注册到 onclick() 的函数测试 x,y 位置。如果它在某个区域内,你可以做任何你必须做的事情。

    我看不出你想做的和这段代码做的有什么区别,乌龟位置的修改只是一个例子,当点击被onclick()捕获时你可以做任何事情,甚至启动一个线程如果你真的需要它(使用Creating Threads in python

    import turtle as t
    from random import randint
    from threading import Thread
    from time import sleep
    
    def threaded_function(arg,t1):
        for i in range(arg):
            print "running",i
            sleep(1)
            t1.forward(i*10)
    
    
    
    def minegoto(x,y) :
        print x,y
        t1.goto(x,y)
        thread = Thread(target = threaded_function, args = (10,t1 ))
        thread.start()
        thread.join()
        print "thread finished...exiting"
    
    wt=t.Screen()
    t1=t.Turtle()
    wt.register_shape("big",((0,0),(30,0),(30,30),(0,30)))
    t1.shape("big")
    wt.onclick(minegoto,btn=1)
    t1.goto(100,100)
    
    t.mainloop()
    

    【讨论】: