Prosíme přihlašte se nebo zaregistrujte.

Přihlašte se svým uživatelským jménem a heslem.

Autor Téma: Python + GTK + threading [vyřešeno]  (Přečteno 1685 krát)

Kamil Hanus

  • Člen
  • **
  • Příspěvků: 221
    • Zobrazit profil
    • kamilhanus.cz
Python + GTK + threading [vyřešeno]
« kdy: 12 Říjen 2011, 18:23:40 »
Zdravím,

pracuji na jedné aplikaci v Pythonu s využitím pyGTK a potřeboval bych poradit se zřejmě banální věcí. Rád bych měl Label pole, ve které by se postupně zleva doprava vysunul text. Bohužel moc znalostí o využití více vláken nemám a níže zobrazený kód mi nefunguje. V podstatě můj problém je takový, že namísto zobrazení okna a následném "vysunutí" textu se neděje nic, dokud neskončí cyklus, který měl zobrazovat text a až potom se zobrazí samotné okno (s již finálně zobrazeným textem).

Mohli byste mi prosím někdo poradit, co dělám špatně? Díky :)

Kód: [Vybrat]
#!/usr/bin/env python
# -*- coding: utf-8 -*-


import time
import threading

try:
  import pygtk
  pygtk.require("2.0")
except:
  pass
try:
import gtk
  import gtk.glade
except:
sys.exit(1)

gtk.gdk.threads_init()

NUM_THREADS = 2

class CT24bar():

def __init__(self, threads=None):


self.gladefile = "main_vzhled.glade"
self.wTree = gtk.glade.XML(self.gladefile)
self.window = self.wTree.get_widget("window1")
color = gtk.gdk.color_parse('#FFFFFF')
self.window.modify_bg(gtk.STATE_NORMAL, color)
self.threads = []

self.text = self.wTree.get_widget("label2")
self.threads.append(ZmenText(self.text))
self.window.show_all()


def run(self):
gtk.main()

class ZmenText(threading.Thread):


def __init__(self, text_label):
threading.Thread.__init__(self)
self.text=text_label
gtk.gdk.threads_enter()
text="Postupně zobrazený text"
tmp=""
for i in text:
tmp = tmp + i

self.text.set_label(tmp)

time.sleep(0.05)
gtk.gdk.threads_leave()


if __name__ == "__main__" :

    application = CT24bar()
    for t in application.threads:
        t.start()
   
    gtk.gdk.threads_enter()
    gtk.main()
    gtk.gdk.threads_leave()


« Poslední změna: 12 Říjen 2011, 19:51:46 od Kamil Hanus »
Only wimps use tape backup: _real_ men just upload their important stuff on ftp, and let the rest of the world mirror it ;)

GdH

  • Moderátor
  • Závislák
  • ***
  • Příspěvků: 3074
    • Zobrazit profil
    • GdH-Notes
Re:Python + GTK + threading
« Odpověď #1 kdy: 12 Říjen 2011, 18:36:35 »
Jestli při tom vykreslování nepotřebuješ opravdu dělat ještě něco jiného, můžeš zapomenout na thready a stačilo by jen v každém průběhu smyčky nechat překreslit GTK změny, protože jinak dokud nepředá callback řízení zpět hlavní smyčce, nic se nekreslí.

Kód: [Vybrat]
while gtk.events_pending():
    gtk.main_iteration_do(False)


Další možností je pak udělat si generátor, který bude volat callback ve zvoleném intervalu a tak je možné 'současně' dělat i jiné věci, nemusí se čekat ve sleepu. Zkrátka se ten cyklus rozloží do několika volání.
A ještě odkaz: http://www.pygtk.org/pygtk2reference/gobject-functions.html#function-gobject--timeout-add
« Poslední změna: 12 Říjen 2011, 18:52:17 od GdH »

Kamil Hanus

  • Člen
  • **
  • Příspěvků: 221
    • Zobrazit profil
    • kamilhanus.cz
Re:Python + GTK + threading
« Odpověď #2 kdy: 12 Říjen 2011, 19:31:44 »
Díky, ten gobject vypadá nadějně. Nicméně i když se mi ve výpisu v terminálu zobrazují znaky postupně, v okně se vše zobrazí až najednou. Což mi přijde divné, protože výpis proměnné mám daný až po nastavení labelu.

Kód: [Vybrat]
def __init__(self, text_label):
def sleeper(tmp):
time.sleep(0.01)
self.text.set_label(tmp)
print "0 - "+tmp
threading.Thread.__init__(self)
self.text=text_label
text="Postupně zobrazený text"
tmp=""
for i in text:
tmp = tmp + i
print tmp
gobject.timeout_add(10, sleeper, tmp)
Only wimps use tape backup: _real_ men just upload their important stuff on ftp, and let the rest of the world mirror it ;)

GdH

  • Moderátor
  • Závislák
  • ***
  • Příspěvků: 3074
    • Zobrazit profil
    • GdH-Notes
Re:Python + GTK + threading
« Odpověď #3 kdy: 12 Říjen 2011, 19:40:51 »
Tos špatně pochopil ten gobject, tim založíš generátor, který bude ve zvoleném intervalu volat zadaný callback (dokud mu nevrátíš False). Tak jak jsi to použil, k tomu je právě ta první varianta, kterou jsem ti dal. Hlavně ani v jednom případě nepotřebuješ thread. Zkrátka:

 
Kód: [Vybrat]
for i in text:
    tmp = tmp + i
    self.text.set_label(tmp)
    while gtk.events_pending():
       gtk.main_iteration_do(False)
    time.sleep(0.05)

Kamil Hanus

  • Člen
  • **
  • Příspěvků: 221
    • Zobrazit profil
    • kamilhanus.cz
Re:Python + GTK + threading
« Odpověď #4 kdy: 12 Říjen 2011, 19:47:22 »
Tak jsem to zkoušel a nefungovalo. Problém byl zřejmě v použití Threadu, bez něj o jede jak má :) Díky moc! K+
Only wimps use tape backup: _real_ men just upload their important stuff on ftp, and let the rest of the world mirror it ;)

GdH

  • Moderátor
  • Závislák
  • ***
  • Příspěvků: 3074
    • Zobrazit profil
    • GdH-Notes
Re:Python + GTK + threading [vyřešeno]
« Odpověď #5 kdy: 18 Listopad 2012, 19:36:52 »
Vzpoměl jsem si na toto vlákno, když jsem dnes začal psát k tomuto tématu na blog, tak to sem přihodim, kdyby se to hodilo. Je to už pro GTK+ 3, ale vlastně je to až na strukturu knihovny stejné i v GTK+ 2.
PyGObject - Aktualizace GUI z callbacku, časovače, i vlákna