2017-09-14 205 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 –