Tkinter + Visual Python + Threads
| stainboy | 26.03.2007 23:36:36 | |
![]() | Witam wszystkich i proszę o pomoc. Uczę się od niedawna pythona i chcę do mojego programu zastosować jakiś interfejs, wybrałem Tkinter. Kod mojego programu który udało mi się do tej pory stworzyć jest nstępujący:
from visual import *
from Tkinter import *
import math,thread, random
R = 2000000
flaga = -1; # główna flaga mająca obsługiwać działanie programu 1 - start animacji 0 - stop itd..
scena = display(title='Planets', width=320 , height=240,range=(R,R,R),\
autoscale = 0, center = (0,0,0))
class param: #parametry obiektu cząsteczka
def __init__(self):
self.vx = 0
self.vy = 0
self.vz = 0
self.x = 0
self.y = 0
self.z = 0
self.fx = 0
self.fy = 0
self.fz =0
self.mass = 0
self.color = (random.random(),random.random(),random.random())
self.tor = curve(pos=[],color=self.color)
self.sphere = sphere(pos=(0,0,0), radius = self.mass, color=self.color, visible = 1)
class czastki: #klasa trzyma N czastek do symulacji
def __init__(self, N):
self.lista = []
for i in range(N):
self.lista.append( param() )
def polozenia(self, N, h): #metoda oblicza nowe położenia
h2p = 0.5*h*h
for i in range(2,N):
self.lista [i].x += h*self.lista [i].vx + h2p*self.lista [i].fx
self.lista [i].y += h*self.lista [i].vy + h2p*self.lista [i].fy
self.lista [i].z += h*self.lista [i].vz + h2p*self.lista [i].fz
self.lista [i].sphere.pos = ( self.lista [i].x, self.lista [i].y, self.lista [i].z)
self.lista [i].tor.append ( pos = ( self.lista [i].x, self.lista [i].y, self.lista [i].z))
def rozmiesc(self, N): #metoda rozmieszcza ciała na początku symulacji
self.lista[0].x= 0
self.lista[0].y =0
self.lista[0].z =0
self.lista[0].m = 1000000000
self.lista[0].sphere.pos = (self.lista[0].x, self.lista[0].y, self.lista[0].z)
self.lista[0].sphere.radius = self.lista[0].m/5000;
self.lista[1].x= 500000
self.lista[1].y =500000
self.lista[1].z = 0
self.lista[1].m = 1000000000
self.lista[1].sphere.pos = (self.lista[1].x, self.lista[1].y, self.lista[1].z)
self.lista[1].sphere.radius = self.lista[0].m/5000;
for i in range(2,N):
self.lista [i].x = random.uniform(-2183000, 2183000)
self.lista [i].y = random.uniform(-2183000, 2183000)
self.lista [i].z = random.uniform(-2183000, 2183000)
self.lista [i].vx = random.uniform(-6500, 6500)
self.lista [i].vy = random.uniform(-6500, 6500)
self.lista [i].vz = random.uniform(-6500, 6500)
self.lista [i].m = random.uniform(109000, 279901)
self.lista [i].sphere.pos = (self.lista [i].x, self.lista [i].y, self.lista [i].z)
self.lista [i].sphere.radius = self.lista [i].m/10;
def predkosc(self, N, h): #metoda oblicza nowe predkosci
hp = 0.5*h;
for i in range (N):
self.lista [i].vx += hp*self.lista [i].fx
self.lista [i].vy += hp*self.lista [i].fy
self.lista [i].vz += hp*self.lista [i].fz
def sily (self, N):
ep = 0
df = 0
for i in range(N):
self.lista [i].fx = 0
self.lista [i].fy = 0
self.lista [i].fz = 0
for j in range(N-1):
for k in range(j+1, N):
dx = self.lista[j].x - self.lista[k].x
dy = self.lista[j].y - self.lista[k].y
dz = self.lista[j].z - self.lista[k].z
d = pow(dx*dx + dy*dy + dz*dz,0.5)
ep += 1/d
r3 = d*d*d
df = (self.lista[j].m * self.lista[k].m*dx)/r3
self.lista[j].fx -= df
self.lista[k].fx += df
df = (self.lista[j].m * self.lista[k].m*dy)/r3
self.lista[j].fy -= df
self.lista[k].fy += df
df = (self.lista[j].m * self.lista[k].m*dz)/r3
self.lista[j].fz -= df
self.lista[k].fz += df
return ep
def Ek(self, N):
e = 0
for i in range(N):
e += 0.5*( (self.lista [i].vx * self.lista [i].vx)\
+ (self.lista [i].vy * self.lista [i].vy))
return e
def animate(self,N,h): #metoda animacji którą nie wiem jak obsłużyć, będzie uzywana w nowym wątku
global flaga
if flaga == 1:
self.polozenia(N, h)
self.predkosc(N, h)
self.sily(N)
self.predkosc(N, h)
self.Ek(N)
class Application: #klasa aplikacji
def __init__(self,root,N,h):
self.czasteczki=czastki(N)
self.czasteczki.rozmiesc(N)
self.frame = Frame(root)
self.frame.pack()
self.button_start = Button(self.frame, text="START",fg="red", command = self.change_flag )
self.button_start.pack(side=BOTTOM)
def change_flag(self): #metoda którą chcę sterowac program narazie tylko 2 wartości
global flaga
print "przed zmiana: " + str(flaga)
flaga = -flaga
print "zmieniono na " + str(flaga)
#----------program -----------------
h = 0.05 #krok symulacji
N = 6 #ilosc czastek
ep = 0 #energia potencjalna
ek = 0 #energia kinetyczna
root = Tk()
app = Application(root,N,h)
thread.start_new_thread(app.czasteczki.animate,(N,h)) #wątek w którym "dzieje" się animacja
root.mainloop()
Program jest symulacją N ciał oddziałujących ze sobą siłami grawitacyjnymi za pomocą samostartującego algorytmu Verleta. Moj problem polega na tym ze nie wiem jak wykożystać globalną flagę w wątku by sterowała mi animacją, gdy jest 1 to leci animacja gdy 0 to stoi. Jeszcze nigdy nie wykożystywałem wątków w programach więc proszę o wyrozumiałość i czekam na propozycje. Pozdrawiam. | |

