2017-09-14 193 views
0

我正在使用Tkinter在树莓派上构建一个非常简单的基于屏幕的实验。我想在屏幕上不断显示一个刺激(所以我的代码列表是win.mainloop()。在每次点击/触摸刺激时,刺激都应该改变位置,我用basic三角通过执行:每次迭代更改值 - python 3

distance = 0.2 
angle_range = list(range(0, 360, 45)) 
xc = (math.sin(angle_range[0] * 0.0174) * distance) + 0.5 
yc = (math.cos(angle_range[0] * 0.0174) * distance) + 0.5 

我然后使用XCYC来定位屏幕上的刺激(在这种情况下,将被视为由Tkinter的一个按钮):

photo = PhotoImage(file="FaceStimulus.png") 
Stimulus = Button(win, command=changePosition) 
Stimulus.config(image=photo) 
Stimulus.place(relx=xc, rely=yc) 

最后是fu nction与按钮

def changePosition(): 
    print("Stimulus pressed") 
    angle_range = random.shuffle(angle_range) 

在功能changePosition我问的位置列表,它并没有真正发生的洗牌有关。刺激始终保持其初始状态。

我可能会缺少一些Python编程的基本逻辑,对不起,如果这是一个微不足道的问题。在写这里之前,我看起来有点在线,我发现了一些方法,但每次我尝试实现它们时,都会运行相同的逻辑错误:如何从函数中重复定义一个变量?

+0

您是否希望刺激显示在屏幕上的任意位置,或者您是否希望基于某种预定义的算法显示它? @antscolony –

+0

我想按钮显示在任何随机位置计算与从列表中提取的角度(范围(0,360,45)) – antscolony

回答

0

一旦声明xc = something,xc就被锁定,除非您进入并更改它,否则不会更改。更改它基于的列表不做任何事情。尝试更新函数中的变量,而不仅仅是列表。

此代码可能不起作用,但希望可以帮助您找出要执行的操作。

def changePosition(): 
    print("Stimulus pressed") 
    random.shuffle(angle_range) 
    xc = (math.sin(angle_range[0] * 0.0174) * distance) + 0.5 
    yc = (math.cos(angle_range[0] * 0.0174) * distance) + 0.5 
    Stimulus.place(relx=xc, rely=yc) 
+0

我明白你的方法,谢谢! 但是,当我尝试实现您的代码时,我回到了之前的位置。我需要一个初始值xc和yc,否则在试验1时(在初始化时)刺激基本上不会显示出来。 我可以通过运行刺激点击计数器来检查这是否为试用1,以便每次点击开始新的试用。我会尽力。 – antscolony

0

见下面我解释片断:

from tkinter import * 
import math 
import random 

class App: 
    def __init__(self, root): 
    self.root = root 
    self.distance = 0.2 
    self.angle_range = list(range(0, 360, 45)) 

    #this is a placeholder for your stimulus 
    self.label = Label(self.root, text="Image Placeholder") 

    self.command() #calls the command to generate the first position 
    self.label.bind("<Button-1>", self.command) #creates a callback whenever the label is clicked with mousebutton 1 
    def command(self, *args): 
    #i'll explain this below the snipper 
    var = random.choice(self.angle_range) 
    self.xc = (math.sin(var * 0.0174) * self.distance) + 0.5 
    self.yc = (math.cos(var * 0.0174) * self.distance) + 0.5 
    self.label.place(relx=self.xc, rely=self.yc) 

root = Tk() 
App(root) 
root.mainloop() 

所以看起来你面前的是,你永远只能调用您的list0th元素所遇到的问题。为了解决这个问题,我添加了self.angle_range[random.randrange(len(self.angle_range))]

让我们来分析一下。

self.angle_range[n]是您的列表,包含我们之前传播的所有元素。所以我们需要一个来自这个列表的随机元素?精细。

因此我们使用random.choice(self.angle_range)这将抓取一个随机元素。

这将从listself.angle_range中返回一个随机元素,根据我们提供的list给出随机坐标。

+0

这按预期工作。也很清楚的解释。我注意到编码的方式与我自己有很大的不同(我的确非常天真)。你知道在哪里可以找到关于这种构建脚本的更多信息吗?谢谢 – antscolony

+0

这是坏的;你正在选择一个可能不同的随机角度来计算x和y坐标,所以这个点不限制在所需的圆上。无论如何,'random.choice(self.angle_range)'是从列表中选择元素的更好方式。 – jasonharper

+0

这是'面向对象的编程'。这是在'tkinter'中编写任何复杂程序的最简单方法之一(显然这是基于意见的)。这个问题可能是更好的解释它,我:https://stackoverflow.com/questions/17466561/best-way-to-structure-a-tkinter-application –