Strona 1 z 1

[python] odzielny wątek, pygtk

: 29 maja 2010, 17:38
autor: makson
Zrobiłem aplikację w Pythonie i przy pomocy Glade przygotowałem dla niej prosty interfejs graficzny. Naciśnięcie przycisku 'Start' wywołuje funkcję wyglądającą mniej-więcej tak (duże uproszczenie, ale oddaje ideę):

Kod: Zaznacz cały

 def button_start(self, widget):
  global lista
  while lista != []:
   wynik = funkcja.licząca(lista[0])
   del lista[0]
  self.logwindow1.set_text(wynik)
Problem jest w tym, że liczenie w pętli 'while' zajmuje dużo czasu. Podczas tego liczenia program jest zamrożony i nic się nie dzieje i nic nie można zrobić. Chciałbym zrobić, żeby po kliknięciu przycisku 'Start' program liczył swoją drogą, a reszta aplikacji działała normalnie. Chciałbym też, żeby podczas liczenia co np. 1 sekundę w 'logwindow1' pokazywał tekst 'wynik' dopóki nie skończy liczyć i wtedy pokazał ostatni 'wynik'. Proszę o pomoc i chciałbym skorzystać z jakiegoś megaprostego i szybkiego w realizacji sposobu na zrobienie tego.
Pozdrawiam.

Odp: [python] odzielny wątek, pygtk

: 29 maja 2010, 19:31
autor: warlock24
być może to się nada

Timer - wątek wykonujący kod po czasie x sekund

Kod: Zaznacz cały

t = threading.Timer(numSec, funcPtr)
t.start()
t.cancel()
o ile pamiętam z pygtk jest jeszcze taka sprawa że wątki działają mizernie jeżeli na początku kodu nie dasz tego

Kod: Zaznacz cały

gtk.gdk.threads_init();

Odp: [python] odzielny wątek, pygtk

: 29 maja 2010, 19:50
autor: luki86
Może da się to na generatorach zrobić, możesz jeszcze spróbować tego sposobu.

Co do logwindow, możesz w nowym wątku uruchomić funkcje tego typu:
while warunek:
rob_cos
time.sleep(1)

Odp: [python] odzielny wątek, pygtk

: 30 maja 2010, 16:24
autor: makson
Dzięki za pomoc robię pewne postępy.
Na początku dodałem:

Kod: Zaznacz cały

import gobject, threading
Następnie po kliknięciu przycisku wywołuję funkcję w innym wątku kodem:

Kod: Zaznacz cały

threading.Thread(target=funkcja.licząca, args=(pierwszy_argument, drugi, trzeci)).start()
Linijkę niżej oddzielny wątek do aktualizowania wyników i funkcje aktualizujące:

Kod: Zaznacz cały

  threading.Thread(target=self.pokaz, args=('', )).start()
  print 'aaku'

 def pokaz2(self, nic):
  self.logwindow1
  self.logwindow1.set_text('a')


 def pokaz(self, nic):
  print 'kupaaa'
  a = 0
  while a < 5:
   print 'kupa1bbb'
   gobject.idle_add(self.pokaz2, '')
   a = a + 1
   time.sleep(0.2)
I na końcu koniecznie:

Kod: Zaznacz cały

# wywołanie aplikacji
if __name__ == "__main__":
 gtk.gdk.threads_init()
 hwg = GUI()
 gtk.main() 
(bez gtk.gdk.threads_init() nie działa!)


Teraz pytanie. Jak zrobić, żeby argumentem do funkcji aktualizującej (pokaz) była wartość liczona w funkcja.licząca?