Tkinter + Visual Python + Threads




stainboy26.03.2007 23:36:36
#
Dołączył: 26.03.2007

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.




Kontakt

Jeśli chcesz się z nami skontaktować napisz na adres: info(at)binboy.org lub odwiedź nasz profil na Facebooku!

O Nas

Serwis binboy.org to kopalnia wiedzy dla wszystkich z branży IT, w szczególności dla programistów i webmasterów. To duży zbiór kursów programowania, tutoriali, darmowych ebooków, setki kodów źródłowych itp.

Bądź w kontakcie

Panel użytkownika

Zaloguj się do panelu użytkownika.
Nie masz konta? Zarejestruj się!
Zapomniałeś hasła?