Re: [Python] Glade3 e statusbar
On Sun, Oct 13, 2013 at 5:53 PM, Marcello wrote: > Si effettivamente il problema è proprio il blocco della mainloop. Lanciando dei processi bloccanti è sempre quello il problema > Ho provato ad utilizzare Tread, ma ottengo lo stesso risultato Utilizzare i thread con gtk è una delle cose più difficili (e inutili) che si possano fare, nonostante decine di post che troverai googlando. Per risolvere puoi fare 2 cose, usare twisted per lanciare un processo asincrono o utilizzare IOChannel, qui di seguito un esempio per la seconda soluzione che ho scritto recentemente, questo aggiorna una textview ma è facilmente modificabile per le tue esigenze, purtoppo non hai messo la parte incriminata, se preferisci invece usare twisted è facilmente traducibile (t.i.r.spawnProcess) from gi.repository import Gtk, GLib class MySpawned(Gtk.Window): def __init__(self): Gtk.Window.__init__(self) vb = Gtk.VBox(False, 5) self.tw = Gtk.TextView() bt = Gtk.Button('Run') bt.connect('clicked', self.process) vb.pack_start(self.tw, True, True, 0) vb.pack_start(bt, False, False, 0) self.add(vb) self.set_size_request(200, 300) self.connect('delete-event', Gtk.main_quit) self.show_all() def run(self): Gtk.main() def process(self, widget, data=None): params = ['python', '-h'] def write_to_textview(io, condition): if condition is GLib.IO_IN: line = io.readline() self.tw.props.buffer.insert_at_cursor(line) return True elif condition is GLib.IO_HUP|GLib.IO_IN: GLib.source_remove(self.source_id) return False self.source_id = None pid, stdin, stdout, stderr = GLib.spawn_async(params, flags=GLib.SpawnFlags.SEARCH_PATH, standard_output=True) io = GLib.IOChannel(stdout) self.source_id = io.add_watch(GLib.IO_IN|GLib.IO_HUP, write_to_textview, priority=GLib.PRIORITY_HIGH) if __name__ == '__main__': s = MySpawned() s.run() ciao -- Gian Mario Tagliaretti GNOME Foundation member gia...@gnome.org ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Glade3 e statusbar
> cmq i problemi rimarranno se blocchi il mainloop lanciando dei processi esterni > e questo mi fa pensare che ho ragione. Si effettivamente il problema è proprio il blocco della mainloop. Ho provato ad utilizzare Tread, ma ottengo lo stesso risultato from threading import Thread from gi.repository import Gtk class Windows(object): def __init__(self): self.ApplicazioneGlade = Gtk.Builder() self.ApplicazioneGlade.add_from_file(PercorsoGlade) self.ApplicazioneGlade.connect_signals(self) self.statusbar = self.ApplicazioneGlade.get_object('statusbar') self.context_id = self.statusbar.get_context_id('statusbar') self.statusbar.push(self.context_id, 'Status . . . . . . . ') def run(self, *args): self.ApplicazioneGlade.get_object("FinestraPrincipale").show() self.model = Gtk.ListStore(str,str,str,str,str) elencoimpianti = self.ApplicazioneGlade.get_object('ElencoImpianti') elencoimpianti.get_selection().set_mode(Gtk.SelectionMode.SINGLE) col1,col2,col3,col4,col5 = range(5) elencoimpianti.set_model(self.model) cell = Gtk.CellRendererText() column2 = Gtk.TreeViewColumn("- Nome Impianto -", cell, text = col2) column2.set_resizable (True) column2.set_sort_column_id(col2) elencoimpianti.append_column (column2) column3 = Gtk.TreeViewColumn("- Codice Impianto -", cell, text = col3) column3.set_resizable (True) column3.set_sort_column_id(col3) elencoimpianti.append_column (column3) column4 = Gtk.TreeViewColumn(" Pers ", cell, text = col4) column4.set_resizable (True) column4.set_sort_column_id(col4) elencoimpianti.append_column (column4) column5 = Gtk.TreeViewColumn(" -PBX- ", cell, text = col5) column5.set_resizable (True) column5.set_sort_column_id(col5) elencoimpianti.append_column (column5) datiDB = pyodbc.connect('DRIVER={};DBQ={};PWD={}'.format(DriverMDB,PercorsoMDB,PwdMDB)) cur = datiDB.cursor() cur.execute("select CapoImpianto,NomeImpianto,CodiceImpianto,NomeSW,TipoCentrale from Impianti where Gestione = '"+gestione+"'") dati = cur.fetchall() for dato in dati: if str(dato[0]) == "None": var1= '' else: var1=str(dato[0]) var2=str(dato[1]) var3=str(dato[2]) var4=str(dato[3]) if str(dato[4]) == "None": var5= '' else: var5=str(dato[4]) record = self.model.append([var1,var2,var3,var4,var5]) cur.close() datiDB.close() Gtk.main() def on_statusbar_show(self, button,obj,data=None): self.statusbar = self.ApplicazioneGlade.get_object('statusbar') self.context_id = self.statusbar.get_context_id('statusbar') self.statusbar.push(self.context_id, self.MessaggioStatusbar) def on_VerTab_clicked(self, button): self.MessaggioStatusbar = 'Hai premuto Verifica Tabella' thread1 = Thread(target=self.on_statusbar_show(self, button,data=None),args=[]) thread1.start() thread1.join() thread2 = Thread(target=self.on_VerTab_clicked2(self),args=[]) thread2.start() thread2.join() def on_VerTab_clicked2(self, button): ... codice che controlla parecchi file di testo .. ... insert INTO DB . Windows().run() Posso risolvere questo problema facilmente senza stravolgere il programma? Ciao Marcello ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Glade3 e statusbar
2013/10/6 Marcello : ciao Marcello, non vedendo tutto il codice posso solo azzardare > def on_statusbar_show(self, button,obj,data=None): > self.statusbar = self.ApplicazioneGlade.get_object('statusbar') self.statusbar = self.ApplicazioneGlade.get_object('statusbar') crei l'oggetto self.statusbar dentro la funzione, sia self.statusbar che self.context_id dovresti crearli dentro l'__init__ della classe, se il controllo dei parecchi file di testo è bloccante (e.g. qualcosa che fai con subprocess.Popen o familiari) il mainloop potrebbe non far in tempo a scrivere il messaggio nella statusbar > > self.context_id = self.statusbar.get_context_id('statusbar') > self.statusbar.push(self.context_id, self.MessaggioStatusbar) > > def on_VerTab_clicked(self, button): > self.MessaggioStatusbar = 'Hai premuto Verifica Tabella' > self.on_statusbar_show(self,button) > . controllo parecchi file di testo qualcosa del genere class MyClass (blabla) def __init__ (blabla, blabla) self.widgets = Gtk.Builder(blabla) self.statusbar = self.widgets.get_object('statusbar') self.context_id = self.statusbar.get_context_id('statusbar') def funzione_che_controlla_tanti_file(self, blabla) ... def on_VerTab_clicked(self, widget, data=None): self.statusbar.push(self.context_id, 'bla bla bla bla') > il messaggio sullo statusbar mi appare non immediatamente quando viene > eseguito ' def on_VerTab_clicked(self, button):' > ma bensì quando finisce di controllare tutti i file di testo. cmq i problemi rimarranno se blocchi il mainloop lanciando dei processi esterni > Questo mi vieta di far vedere sullo statusbar quale file sta elaborando e questo mi fa pensare che ho ragione, come li lanci questi controlli? > Un grazie a Gian Mario per tutte le dritte che mi ha dato fino adesso figurati, siam qui apposta. ciao -- Gian Mario Tagliaretti GNOME Foundation member gia...@gnome.org ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Glade3 e statusbar
> Aggiornare a pygobject.eheh era subliminale ma non troppo, dopo una settimana di lavoro (considerando che potrei definirmi 'un programmatore della domenica') sono riuscito: 1 - ad aggiornare il mio programma a pygobject (c'erano anche i file di glade da modificare) 2 - a far funzionare statusbar però mi è sorto un problemino def on_statusbar_show(self, button,obj,data=None): self.statusbar = self.ApplicazioneGlade.get_object('statusbar') self.context_id = self.statusbar.get_context_id('statusbar') self.statusbar.push(self.context_id, self.MessaggioStatusbar) def on_VerTab_clicked(self, button): self.MessaggioStatusbar = 'Hai premuto Verifica Tabella' self.on_statusbar_show(self,button) . controllo parecchi file di testo il messaggio sullo statusbar mi appare non immediatamente quando viene eseguito ' def on_VerTab_clicked(self, button):' ma bensì quando finisce di controllare tutti i file di testo. Questo mi vieta di far vedere sullo statusbar quale file sta elaborando. Come posso risolvere? Un grazie a Gian Mario per tutte le dritte che mi ha dato fino adesso Saluti Marcello > ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Glade3 e statusbar
On Mon, Sep 30, 2013 at 4:43 PM, Marcello wrote: > Ok ho capito il messaggio... Aggiornare a pygobject. eheh era subliminale ma non troppo, ma cmq lo stesso esempio funziona anche con pygtk, bastano poche modifiche. > ho scaricato ed installato 'pygobject-2.28.3.win32-py2.7.exe' quello è il vecchio pygobject per GObject 2.xx, per la versione 3 scarica questo: https://code.google.com/p/osspack32/downloads/detail?name=pygi-aio-3.4.2rev11.7z&can=2&q=/ che ha dentro tutto, incluso glade3, devhelp, e tutto il cucuzzaro Puoi far riferimento a questa pagina [1] per capire le differenze con PyGTK, ci ho messo anche le istruzioni per fare il package con cx_freeze su windows con un esempio di setup.py (se sei interessato al packaging) [1] https://wiki.gnome.org/PyGObject ciao -- Gian Mario Tagliaretti GNOME Foundation member gia...@gnome.org ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Glade3 e statusbar
Ok ho capito il messaggio... Aggiornare a pygobject. ho scaricato ed installato 'pygobject-2.28.3.win32-py2.7.exe' ma quando faccio from gi.repository import Gtk mi restituisce Traceback (most recent call last): File "", line 1, in ImportError: No module named gi.repository quale file devo installare per win32? Ciao Marcello ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Glade3 e statusbar
On Sun, Sep 29, 2013 at 4:14 PM, Marcello wrote: > no non va. from gi.repository import Gtk class StatusSample(Gtk.Application): def __init__(self): Gtk.Application.__init__(self, application_id="org.app.StatusSample") self.main_window = Gtk.Window(Gtk.WindowType.TOPLEVEL) self.main_window.set_default_size(200, 150) vb = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.main_window.add(vb) button = Gtk.Button("Push Message") button.connect("clicked", self.on_button_push_clicked) vb.pack_start(button, True, True, 0) button = Gtk.Button("Pop message") button.connect("clicked", self.on_button_pop_clicked) vb.pack_start(button, True, True, 0) self.status = Gtk.Statusbar() vb.pack_start(self.status, True, True, 0) self.context = self.status.get_context_id("my_status") self.count = 0 def do_activate(self): self.add_window(self.main_window) self.main_window.set_position(Gtk.WindowPosition.CENTER) self.main_window.show_all() def do_startup(self): Gtk.Application.do_startup(self) self.status.push(self.context, "Primo Messaggio") def on_button_push_clicked(self, button, data=None): self.status.push(self.context, "Messaggio numero %d" % self.count) self.count += 1 def on_button_pop_clicked(self, button, data=None): self.status.pop(self.context) if __name__ == "__main__": statussample = StatusSample() statussample.run(None) ciao -- Gian Mario Tagliaretti GNOME Foundation member gia...@gnome.org ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Glade3 e statusbar
>> def Compila(self,obj): >> self.statusbar.push(self.context_id, 'Cambia Messaggio Statusbar') >prova così (untested) no non va. ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Glade3 e statusbar
2013/9/29 Marcello : > def Compila(self,obj): > self.statusbar.push(self.context_id, 'Cambia Messaggio Statusbar') prova così (untested) ciao -- Gian Mario Tagliaretti GNOME Foundation member gia...@gnome.org ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Glade3 e statusbar
>>> Dal codice che hai postato il metodo "Compila" non viene mai eseguito. >> >> si, e vero, ma ho postato solo parte del codice mettendo solo la parte >> interessata. >era interessante vedere anche quando il metodo viene eseguito, >altrimenti non si capisce perchè non ti funziona. aggiungo richiamo class CreaGUI: def __init__(self): self.ApplicazioneGlade = gtk.glade.XML(PercorsoGlade) self.EventiGlade ={"on_FinestraPrincipale_delete_event":gtk.main_quit, "on_VerTab_clicked":self.VerificaTab, "on_ContrRemoto_clicked":self.ContrRemoto, "on_CopiaImpianti_clicked":self.CopiaImpianti, "on_OpenPers_clicked":self.ApreSaePers, "on_ElencoImpianti_row_activated":self.SelezioneImpianto, "on_VisNumImp_clicked":self.VisNumImp, "on_SincroDB_clicked":self.SincroDB, "on_Compila_clicked":self.Compila, "on_VisualizzaCopia_clicked":self.VisualizzaCopia, } self.statusbar = self.ApplicazioneGlade.get_widget('statusbar') self.context_id = self.statusbar.get_context_id('statusbar') self.statusbar.push(self.context_id, "Messaggio di prova statusbar") # ... # ... gtk.main() def Compila(self,obj): context_id = self.statusbar.get_context_id('statusbar') self.statusbar.push(context_id, 'Cambia Messaggio Statusbar') ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Glade3 e statusbar
2013/9/29 Marcello : >> Dal codice che hai postato il metodo "Compila" non viene mai eseguito. > > si, e vero, ma ho postato solo parte del codice mettendo solo la parte > interessata. era interessante vedere anche quando il metodo viene eseguito, altrimenti non si capisce perchè non ti funziona. ciao -- Gian Mario Tagliaretti GNOME Foundation member gia...@gnome.org ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Glade3 e statusbar
Ciao e grazie per la risposta, > Ad ogni modo, a prescindere se usi GTK2 o GTK3 gtk.glade.XML è > super-deprecato, usa gtk.Builder al suo posto. provvederò ad aggiornare ad gtk.Builder > Dal codice che hai postato il metodo "Compila" non viene mai eseguito. si, e vero, ma ho postato solo parte del codice mettendo solo la parte interessata. ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Glade3 e statusbar
2013/9/29 Marcello : > Ciao a tutti ciao Marcello, ho un po' di commenti a parte il codice, innanzi tutto ti consiglio di non usare le "vecchie" PyGTK ma di usare pygobject introspection che utilizza le nuove GTK3, PyGTK non è più mantenuto ed è sconsigliato per scrivere nuovo codice. [1][2] Ad ogni modo, a prescindere se usi GTK2 o GTK3 gtk.glade.XML è super-deprecato, usa gtk.Builder al suo posto. [3] Questo consiglio puoi anche non ascoltarlo, usa uno stile consistente per i nomi di classi/metodi/variabili, e.g. nomi classi Capital, metodi e variabili lowercase, etc... > quando lo eseguo si apre correttamente la finestra e sullo statusbar mi > compare 'Messagio di prova...' . la statusbar tiene uno stack di messaggi per ogni context, ovvero a chiamate successive di push() il messaggio viene sostituito con quello che hai appena inviato, se devi rimuovere il messaggio puoi usare pop() che ti elimina l'ultimo dallo stack, attenzione che se quello mostrato è di un altro context potrebbe non fare quello che pensi. [4] > Ho la necessità, quando viene richiamato Compila, di cambiare il messaggio. > Dove sbaglio? Dal codice che hai postato il metodo "Compila" non viene mai eseguito. [1] https://wiki.gnome.org/PyGObject [2] https://python-gtk-3-tutorial.readthedocs.org/en/latest/index.html [3] https://developer.gnome.org/gtk3/3.10/GtkBuilder.html [4] https://developer.gnome.org/gtk3/3.10/GtkStatusbar.html#gtk-statusbar-pop ciao -- Gian Mario Tagliaretti GNOME Foundation member gia...@gnome.org ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python