Hi,
habe nun vor ein GUI zu bauen und möchte das aus einem anderen Thread heraus verändern.
Die Funktionen zum Ändern habe ich auch schon erstellt und ich kann sie auch aufrufen.
Das Problem ist nur, die Änderungen wirken sich nicht auf das GUI aus.
Kann ich das GUI irgendwie refreshen oder so etwas in der Art?
Oder geht das irgendwie anders?
Bin über jeden Tipp dankbar.
Viele Grüße
Maxi
Veränderungen nach gtk.main() durch anderen Thread
Vielleicht magst du ja etwas Code zeigen, damit man auch sieht, was du machst. Im Allgemeinen gibt es bei GUIs und Threads doch einiges zu beachten, ich bin mir sicher, dass die Forensuche da einige Beiträge finden dürfte.
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
-
- User
- Beiträge: 110
- Registriert: Freitag 25. Dezember 2009, 03:42
Hi,
der Code ist etwas lang, ich breche ihn mal herunter.In einem zusätzlichem Thread läuft auch noch gtk.main().
Natürlich sind die eigentlichen Funktionen viel komplexer, doch ist es hier das gleiche Problem - interface.show() wird ausgeführt und die Eigenschaft des Fensters auf show gestellt, doch es wird einfach nicht angezeigt.
Wenn ich jetzt aber zwei Fenster habe und z.B. bei Klick auf das X des einen Fensters als Callback interface.show() auslöse geht es, das Fenster wird sichtbar.
Viele Grüße
Maxi
der Code ist etwas lang, ich breche ihn mal herunter.
Code: Alles auswählen
class MainWindow():
#...
def show(self):
self.mainWindow.show()
#...
class MainThread():
def __init__(self, interface):
self.mainWindow = interface
#...
def run(self):
self.mainWindow.show()
#...
interface = MainWindow()
thread = MainThread(interface)
thread.start()
Natürlich sind die eigentlichen Funktionen viel komplexer, doch ist es hier das gleiche Problem - interface.show() wird ausgeführt und die Eigenschaft des Fensters auf show gestellt, doch es wird einfach nicht angezeigt.
Wenn ich jetzt aber zwei Fenster habe und z.B. bei Klick auf das X des einen Fensters als Callback interface.show() auslöse geht es, das Fenster wird sichtbar.
Viele Grüße
Maxi
Hallo
Gruß
Andyh
Code: Alles auswählen
import gtk
import gobject
import threading
import time
gobject.threads_init()
class MainWindow():
def __init__(self):
self.mainWindow = gtk.Window()
self.label = gtk.Label("hallo das da unten ist ein Button")
self.button = gtk.Button("ok gefunden")
self.layout = gtk.VBox()
self.mainWindow.add(self.layout)
self.layout.pack_start(self.label)
self.layout.pack_start(self.button)
def show(self):
self.mainWindow.show_all()
def change_text(self, new_text):
self.label.set_text(new_text)
class MainThread(threading.Thread):
def __init__(self, interface):
threading.Thread.__init__(self)
self.mainWindow = interface
def run(self):
gtk.gdk.threads_enter()
self.mainWindow.show()
gtk.gdk.threads_leave()
time.sleep(5)
gtk.gdk.threads_enter()
self.mainWindow.change_text("hallo neuer text")
gtk.gdk.threads_leave()
interface = MainWindow()
thread = MainThread(interface)
thread.start()
gtk.main()
Andyh
Meinen Dickschädel schon bemerkt?
Ich bin jetzt FACHARBEITER (Zerspanungsmechaniker)!!!
[code]import sys
if sys.platform == "win32":
print "this program only runs on operating systems!!!"
sys.TotalError()[/code]
Ich bin jetzt FACHARBEITER (Zerspanungsmechaniker)!!!
[code]import sys
if sys.platform == "win32":
print "this program only runs on operating systems!!!"
sys.TotalError()[/code]
-
- User
- Beiträge: 110
- Registriert: Freitag 25. Dezember 2009, 03:42
Hi,
sorry, dass ich mich so lange nicht mehr gemeldet habe - Ich hatte viel zu tun.
Dein Beispiel funktioniert bei mir nicht.
Main Rechner hängt sich einfach auf und ich konnte ihn nur noch ausschalten.
Mittlerweile bin ich von Thread auf Multiprogressing umgestiegen.
Hier bekomme ich folgenden Fehler:
Viele Grüße
Maxi
sorry, dass ich mich so lange nicht mehr gemeldet habe - Ich hatte viel zu tun.
Dein Beispiel funktioniert bei mir nicht.
Main Rechner hängt sich einfach auf und ich konnte ihn nur noch ausschalten.
Mittlerweile bin ich von Thread auf Multiprogressing umgestiegen.
Hier bekomme ich folgenden Fehler:
Code: Alles auswählen
python: ../../src/xcb_io.c:242: process_responses: Assertion `(((long) (dpy->last_request_read) - (long) (dpy->request)) <= 0)' failed.
Maxi
Unter Windows funktioniert das nicht. Da kannst du nicht die GTK-Widgets aus einem anderen Thread verändern (außer aus Threads, die durch gobject gestartet wurden, vielleicht kommt das für dich auch in Frage).
Prinzipiell entspricht dein Vorgehen aber auch einem schlechten Prinzip. Schau dir mal das MVC-Pattern an. Dann genügt es, wenn du die Daten aus dem anderen Thread veränderst und die GUI aktualisiert diese regelmäßig.
Prinzipiell entspricht dein Vorgehen aber auch einem schlechten Prinzip. Schau dir mal das MVC-Pattern an. Dann genügt es, wenn du die Daten aus dem anderen Thread veränderst und die GUI aktualisiert diese regelmäßig.
-
- User
- Beiträge: 110
- Registriert: Freitag 25. Dezember 2009, 03:42
Hi,
Es geht um eine Netztwerk Anwendung, wenn die Verbindung getrennt wurde, soll das angezeigt werden.
Dazu ruft mein Programm eine Funktion im Controller auf, die wiederum eine Funktion im GUI auslöst.
Die Aktion ist ein show auf ein in Glade definiertes Fenster mit einer Fehlermeldung.
Naja, und eben dieses Fenster wird nicht angezeigt.
/* Edit:
Im Grunde funktioniert es so wie: http://de.wikipedia.org/wiki/Beobachter ... _in_Python
Bis darauf, dass der Variable kein _ vorangestellt ist.
Und dass es nur einen Überwacher gibt, der Controller.
*/
Viele Grüße
Maxi
Habe ich auch nicht benutzt .Unter Windows funktioniert das nicht.
Nein, da das Programm auch ohne GTK laufen soll - das GUI ist eigentlich eine Art AddOn.(außer aus Threads, die durch gobject gestartet wurden, vielleicht kommt das für dich auch in Frage)
Eigentlich ist es so ähnlich.Prinzipiell entspricht dein Vorgehen aber auch einem schlechten Prinzip. Schau dir mal das MVC-Pattern an. Dann genügt es, wenn du die Daten aus dem anderen Thread veränderst und die GUI aktualisiert diese regelmäßig.
Es geht um eine Netztwerk Anwendung, wenn die Verbindung getrennt wurde, soll das angezeigt werden.
Dazu ruft mein Programm eine Funktion im Controller auf, die wiederum eine Funktion im GUI auslöst.
Die Aktion ist ein show auf ein in Glade definiertes Fenster mit einer Fehlermeldung.
Naja, und eben dieses Fenster wird nicht angezeigt.
/* Edit:
Im Grunde funktioniert es so wie: http://de.wikipedia.org/wiki/Beobachter ... _in_Python
Bis darauf, dass der Variable kein _ vorangestellt ist.
Und dass es nur einen Überwacher gibt, der Controller.
*/
Viele Grüße
Maxi
Aber laut deiner Beschreibung läuft doch schon der GTK Loop?maxi_king_333 hat geschrieben:Nein, da das Programm auch ohne GTK laufen soll - das GUI ist eigentlich eine Art AddOn.(außer aus Threads, die durch gobject gestartet wurden, vielleicht kommt das für dich auch in Frage)
Ich sehe anhand dieser (zweiten) Beschreibung gar keinen sinnvollen Zusammenhang zum Ausgangsproblem... Vielleicht kannst das alles nochmal zusammenfassen.
-
- User
- Beiträge: 110
- Registriert: Freitag 25. Dezember 2009, 03:42
Hi,
Aufbau des Programms:
Der Controller startet das GUI.
gtk.main wird über Multiprocessing gestartet.
Das GUI erscheint und nun kann man über es den Netzwerk Monitor starten.
Dieser wartet nun im Hintergrund auf Befehle.
Sollte die Verbindung zwischen Netzwerk Monitor und dem anderen Computer abbrechen, dann löst der Monitor im Controller eine Funktion aus.
Diese manipuliert wiederum das GUI - Sie stellt das vorbereitete Error Fenster auf sichtbar und sorgt dafür, dass ich wieder auf den Verbinden Button klicken kann.
Es funktioniert alles auch soweit, nur die Änderungen werden nicht sichtbar.
Rufe ich aber die gleiche Funktion über z.B. das Pressed Event eines Buttons auf funktioniert es ohne Probleme.
Viele Grüße
Maxi
Aufbau des Programms:
- Netzwerk Monitor
- Controller
- GUI
Der Controller startet das GUI.
gtk.main wird über Multiprocessing gestartet.
Das GUI erscheint und nun kann man über es den Netzwerk Monitor starten.
Dieser wartet nun im Hintergrund auf Befehle.
Sollte die Verbindung zwischen Netzwerk Monitor und dem anderen Computer abbrechen, dann löst der Monitor im Controller eine Funktion aus.
Diese manipuliert wiederum das GUI - Sie stellt das vorbereitete Error Fenster auf sichtbar und sorgt dafür, dass ich wieder auf den Verbinden Button klicken kann.
Es funktioniert alles auch soweit, nur die Änderungen werden nicht sichtbar.
Rufe ich aber die gleiche Funktion über z.B. das Pressed Event eines Buttons auf funktioniert es ohne Probleme.
Viele Grüße
Maxi
Hallo
Lass doch mal ein bisschen Code sehen.
Der von der gui und die stelle im Controller die die gui anzeigt/verändert.
Gruß
Andyh
Lass doch mal ein bisschen Code sehen.
Der von der gui und die stelle im Controller die die gui anzeigt/verändert.
Gruß
Andyh
Meinen Dickschädel schon bemerkt?
Ich bin jetzt FACHARBEITER (Zerspanungsmechaniker)!!!
[code]import sys
if sys.platform == "win32":
print "this program only runs on operating systems!!!"
sys.TotalError()[/code]
Ich bin jetzt FACHARBEITER (Zerspanungsmechaniker)!!!
[code]import sys
if sys.platform == "win32":
print "this program only runs on operating systems!!!"
sys.TotalError()[/code]
-
- User
- Beiträge: 110
- Registriert: Freitag 25. Dezember 2009, 03:42
Hi,
hier ist der Code von dem Haupt Fenster und der Initialisierung.
Viele Grüße
Maxi
hier ist der Code von dem Haupt Fenster und der Initialisierung.
Code: Alles auswählen
import gtk
import gtk.glade
import gtk.gdk
class InterfaceMain():
def __init__(self, api):
self.api = api # Der Controller
def start(self):
self.mainWindow = MainWindow(self)
gtkmainProcess = Process(target=gtk.main, args=())
gtkmainProcess.start()
def stop(self):
gtk.main_quit()
class MainWindow():
def __init__(self, interface):
self.interface = interface
self.gladefile = "./interface/mainWindow.glade"
self.main = gtk.glade.XML(self.gladefile)
self.mainWindow=self.main.get_widget("MainWindow")
def show(self): # Wird von dem Controller aufgerufen.
self.mainWindow.show()
def hide(self): # Wird von dem Controller aufgerufen.
self.mainWindow.hide()
Maxi
Bitte achte in Zukunft darauf, Probleme möglichst genau zu beschreiben und möglichst auf ein Minimum zu reduzieren, so dass du dann *ausführbaren* Code zeigen kannst, mit dem man das Problem reproduzieren kann.
Bei deinem ersten Post sprichst du noch von Threads -- in deinem letzten Beispiel sind aber Prozesse zu sehen, keine Threads. Das ist ein Unterschied. Du startest die Gtk-Hauptschleife in einem anderen Prozess -- warum?
Bei deinem ersten Post sprichst du noch von Threads -- in deinem letzten Beispiel sind aber Prozesse zu sehen, keine Threads. Das ist ein Unterschied. Du startest die Gtk-Hauptschleife in einem anderen Prozess -- warum?
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
-
- User
- Beiträge: 110
- Registriert: Freitag 25. Dezember 2009, 03:42
Hi,
wie ich schon sagte bin ich von Thread auf Multiprocessing umgestiegen.
Außerdem wollte die Libnotify Bibliothek nicht mir Threads funktionieren.
Glade File gibt es hier: http://pastebin.com/m3bff74
Viele Grüße
Maxi
wie ich schon sagte bin ich von Thread auf Multiprocessing umgestiegen.
Ganz einfach deshalb, weil ich es besser finde, wenn die Prozesse vom Betriebssystem verwaltet werden.maxi_king_333 hat geschrieben:Hi,
sorry, dass ich mich so lange nicht mehr gemeldet habe - Ich hatte viel zu tun.
Dein Beispiel funktioniert bei mir nicht.
Main Rechner hängt sich einfach auf und ich konnte ihn nur noch ausschalten.
Mittlerweile bin ich von Thread auf Multiprogressing umgestiegen.
Hier bekomme ich folgenden Fehler:Viele GrüßeCode: Alles auswählen
python: ../../src/xcb_io.c:242: process_responses: Assertion `(((long) (dpy->last_request_read) - (long) (dpy->request)) <= 0)' failed.
Maxi
Außerdem wollte die Libnotify Bibliothek nicht mir Threads funktionieren.
Trundle hat geschrieben:Bitte achte in Zukunft darauf, Probleme möglichst genau zu beschreiben und möglichst auf ein Minimum zu reduzieren, so dass du dann *ausführbaren* Code zeigen kannst, mit dem man das Problem reproduzieren kann.
Code: Alles auswählen
from multiprocessing import Process
import time
import gtk
import gtk.glade
class InterfaceMain():
def __init__(self):
self.mainWindow = MainWindow(self)
self.mainWindow.show()
gtkmainProcess = Process(target=gtk.main, args=())
gtkmainProcess.start()
def stop(self):
gtk.main_quit()
class MainWindow():
def __init__(self, interface):
self.interface = interface
self.gladefile = "./interface/mainWindow.glade"
self.main = gtk.glade.XML(self.gladefile)
self.mainWindow=self.main.get_widget("MainWindow")
def show(self): # Wird von dem Controller aufgerufen.
self.mainWindow.show()
def hide(self): # Wird von dem Controller aufgerufen.
self.mainWindow.hide()
print "Show"
mainInterface = MainInterface()
print "Sleep"
time.sleep(10)
print "Hide"
mainInterface.mainWindow.hide()
Viele Grüße
Maxi
Ja, meine Frage war wohl eher, warum eigentlich Prozesse. Jedenfalls kannst du nicht einfach die Gtk-Hauptschleife in einem anderen Prozess laufen lassen. Das heißt, können schon, bringt dir aber nichts, weil dein ursprünglicher Prozess auch eine Hauptschleife braucht. Oder alle GUI-Manipulationen müssen im neuen Prozess stattfinden.
Du solltest dir im klaren darüber sein, dass die beiden Prozesse so gesehen nichts miteinander zu tun haben.
Du solltest dir im klaren darüber sein, dass die beiden Prozesse so gesehen nichts miteinander zu tun haben.
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
-
- User
- Beiträge: 110
- Registriert: Freitag 25. Dezember 2009, 03:42
Ja... Hat er ja, in dem Fall time.sleep(10) und in meiner richtigen Anwendung wird der Prozess über eine Klasse initialisiert welche eine Funktion main_loop() hat, die jeden laufenden Prozess aufruft und wartet bis er beendet ist.Ja, meine Frage war wohl eher, warum eigentlich Prozesse. Jedenfalls kannst du nicht einfach die Gtk-Hauptschleife in einem anderen Prozess laufen lassen. Das heißt, können schon, bringt dir aber nichts, weil dein ursprünglicher Prozess auch eine Hauptschleife braucht.
Nötig ist das, weil gtk.main() nicht die Hauptschleife sein darf, da wie schon gesagt, das Programm auch ohne gtk funktionieren soll.
Dann liegt es bestimmt da dran.´Oder alle GUI-Manipulationen müssen im neuen Prozess stattfinden.
Du solltest dir im klaren darüber sein, dass die beiden Prozesse so gesehen nichts miteinander zu tun haben.
Wie kann ich sie denn im neuen Prozess ausführen?
Ich würde dir dringend zu irgendeiner Form von IPC (z.B. xmlrpc ist ganz nett und relativ simpel, umfangreichere und ausgereiftere Möglichkeit wäre u.a. noch Pyro) raten und die Prozesse getrennt verwalten und starten.
Das, was du da geplant hast, lässt sich (wenn überhaupt) dann nur sehr umständlich lösen und ist IMHO auch kein schöner Ansatz.
Das, was du da geplant hast, lässt sich (wenn überhaupt) dann nur sehr umständlich lösen und ist IMHO auch kein schöner Ansatz.
-
- User
- Beiträge: 110
- Registriert: Freitag 25. Dezember 2009, 03:42
Hi,
Du meinst doch: http://docs.python.org/library/xmlrpclib.html
So wie ich das sehe, läuft da die Kommunikation übers Netzwerk und das finde ich eigentlich nicht gut.
Ich werde es mir trotzdem mal ausprobieren und mich wieder melden.
Vielen Dank und Viele Grüße
Maxi
Du meinst doch: http://docs.python.org/library/xmlrpclib.html
So wie ich das sehe, läuft da die Kommunikation übers Netzwerk und das finde ich eigentlich nicht gut.
Ich werde es mir trotzdem mal ausprobieren und mich wieder melden.
Vielen Dank und Viele Grüße
Maxi
Hallo
Ich habe seit neuestem den dbus für mich entdeckt, ist auch ganz simpel.
http://dbus.freedesktop.org/doc/dbus-py ... orial.html
Gruß
Andyh
Ich habe seit neuestem den dbus für mich entdeckt, ist auch ganz simpel.
http://dbus.freedesktop.org/doc/dbus-py ... orial.html
Gruß
Andyh
Meinen Dickschädel schon bemerkt?
Ich bin jetzt FACHARBEITER (Zerspanungsmechaniker)!!!
[code]import sys
if sys.platform == "win32":
print "this program only runs on operating systems!!!"
sys.TotalError()[/code]
Ich bin jetzt FACHARBEITER (Zerspanungsmechaniker)!!!
[code]import sys
if sys.platform == "win32":
print "this program only runs on operating systems!!!"
sys.TotalError()[/code]
-
- User
- Beiträge: 110
- Registriert: Freitag 25. Dezember 2009, 03:42
Hi,
das Ding scheint ganz gut zu sein, ist aber nicht Teil er Standard Bibliothek und unter Windows bekomme ich nur schwer zum laufen (so wie ich das sehe).
Ich benutzte zwar kein Windows aber ich habe extra Python als Sprache gewählt, weil sie unter verschiedenen Plattformen läuft und ich so mein Programm auch den Windows Usern zugänglich machen kann.
xmlrpc läuft übers Netzwerk und deshalb möchte ich es eigentlich auch nicht verwenden und Pyro ist wieder nicht Standard.
Habe jetzt aber eine Idee, wenn es wirklich daran liegt, dass gtk.main() in einem Anderen Prozess läuft, dann starte ich einfach mein ganzes Interface als Prozess und kann dort dann direkt gtk.main() als Hauptschleife laufen lassen.
Viele Grüße
Maxi
das Ding scheint ganz gut zu sein, ist aber nicht Teil er Standard Bibliothek und unter Windows bekomme ich nur schwer zum laufen (so wie ich das sehe).
Ich benutzte zwar kein Windows aber ich habe extra Python als Sprache gewählt, weil sie unter verschiedenen Plattformen läuft und ich so mein Programm auch den Windows Usern zugänglich machen kann.
xmlrpc läuft übers Netzwerk und deshalb möchte ich es eigentlich auch nicht verwenden und Pyro ist wieder nicht Standard.
Habe jetzt aber eine Idee, wenn es wirklich daran liegt, dass gtk.main() in einem Anderen Prozess läuft, dann starte ich einfach mein ganzes Interface als Prozess und kann dort dann direkt gtk.main() als Hauptschleife laufen lassen.
Viele Grüße
Maxi