GNOME-Panel und Nachrichten per Netzwerk anzeigen

Programmierung für GNOME und GTK+, GUI-Erstellung mit Glade.
Antworten
Fred78
User
Beiträge: 3
Registriert: Mittwoch 18. März 2009, 13:16
Wohnort: Kassel

Mittwoch 18. März 2009, 13:59

Hallo

Dies ist mein erster Beitrag hier im Forum. Ich möchte für meine Arbeit ein GNOME-Panel-Plugin programmieren (System: Linux, Desktop: GNOME), das auf einem Netzwerksocket lauscht und jeweils jeweils eine Zeile empfängt. Diese Zeile soll dann als Nachricht im Panel angezeigt werden. Ich habe mir unter anderem das Giplet-Plugin angesehen und versucht, daraus ein Programm zu entwerfen, doch leider funktioniert das so nicht.

Ich bin soweit gekommen, dass ich ein Plugin erstellen und im Panel anzeigen lassen kann, der Serversocket wird geöffnet, die Zeile empfangen und das Socket wieder geschlossen. Alles wunderbar, nur wie kann ich das Plugin so programmieren, dass es in einer Endlosschleife auf dem Socket lauscht, das Label entsprechend ändert und sich sofort darauf neu zeichnet und wieder lauscht? In meinen bisherigen Versuchen wird das Label erst dann angezeigt, wenn ich das Programm mit return gtk.TRUE beende.

Ein eigentlich kurzes Programm, aber ich komme trotz Suche bei Google nicht weiter. Wenn Jemand eine Vorschlag oder ein kurzes Programm wäre das klasse.

Schöne Grüße :-)
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Mittwoch 18. März 2009, 16:28

Gib doch mal den bisherigen Code.

Du musst einen Thread erstellen, der im Hintergrund lauscht und, sollte er etwas empfangen haben, eben das Zeugs anzeigt.
Fred78
User
Beiträge: 3
Registriert: Mittwoch 18. März 2009, 13:16
Wohnort: Kassel

Mittwoch 18. März 2009, 18:36

Hallo

Danke für Deine Antwort. Unten steht der bisherige Code, den ich aus Giplet entnommen und meinen Bedürfnissen entsprechend verändert habe. Das Programm sollte nach Möglichkeit in der Funktion getLine() bei accept blockieren und nach Empfang einer Nachricht das Label ändern und dann neu zeichnen.

Kurze ergänzende Frage: Wird das Applet erst dann angezeigt, wenn das eigentliche Programm mit return.gtk beendet wird? In diesem Falle müsste ich dann einen Fork machen, in dem getLine() und repaint in einer Endlosschleife läuft?

Sorry, ich bin noch nicht so lange dabei mit Python, aber die ersten Versuche machen schon Spaß :-)
-------------------------------

Code: Alles auswählen

#!/usr/bin/env python

import os
import sys
import pygtk
pygtk.require('2.0')
import gtk
import gnomeapplet
import gnome.ui
import socket
import fcntl
import struct
import re
import string

class messageWin:
    def __init__(self, applet, iid):
        self.applet = applet
        self.label = gtk.Label('Noch keine Nachrichten')
        self.applet.add(self.label)

    def cleanup(self, event):
	del self.applet

    def getLine(self):
	while True:
		print "in der Funktion getLine() ..."
		s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
		s.bind(('', 4000))
		s.listen(1)
		sock,addr = s.accept()
		l = sock.recv(1024)
		print l
		self.label.set_text(l)

def giplet_factory(applet, iid):
	a = messageWin(applet, iid)
	return gtk.TRUE

# if True: damit zum Testen das Applet-Window immer als richtiges Window angezeigt wird
if True: 
#if len(sys.argv) > 1 and sys.argv[1] == 'run-in-window':
	main_window = gtk.Window(gtk.WINDOW_TOPLEVEL)
	main_window.set_title("Scan")
	main_window.connect("destroy", gtk.main_quit)
	app = gnomeapplet.Applet()
	giplet_factory(app, None)
	app.reparent(main_window)
	main_window.show_all()
	gtk.main()
	sys.exit()

gnomeapplet.bonobo_factory("OAFIID:GNOME_GipletApplet_Factory", gnomeapplet.Applet.__gtype__, "Giplet IP Viewer", "0", giplet_factory)

Edit by Gerold: Code in Code-Tags gesetzt.
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Mittwoch 18. März 2009, 20:36

Du weißt aber schon, wozu es Code-Tags gibt?
Fred78
User
Beiträge: 3
Registriert: Mittwoch 18. März 2009, 13:16
Wohnort: Kassel

Mittwoch 18. März 2009, 22:26

@Dauerbaustelle: Tut mir leid, ich hatte vergessen, den Code in CodeTags zu setzen. Danke an Gerold für die Korrektur.

zum Thema zurück: In GObject gibt es die Möglichkeit, per timeout_add eine Funktion regelmäßig ausführen zu lassen. Natürlich macht es keinen Sinn, alle paar Sekunden einen Socket zu öffnen, um zu sehen, ob ein Client etwas gesendet hat und es dann wieder zu schließen, nur um es gleich darauf wieder zu öffnen. Alle Beispiele, die ich bisher duchgesehen habe, arbeiten mit dieser Methode, um alle paar Sekunden bestimmte Werte, z.B. CPU-Temp, Netzauslastung, IP-Adresse etc. auszulesen und die Anzeige zu aktualisieren. Mein Thread dagegen darf nur einmal aufgerufen werden, um dann in einer Endlosschleife Nachrichten zu empfangen und anzeigen. Ich arbeite mich weiter in Python ein und schreibe hier die Lösung hin, wenn ich sie gefunden habe.

Noch kurz zur Erklärung, wieso, weshalb, warum: In unserer Firma arbeiten die Computer am Produktionsband unter Linux. Im oberen Bildschirmbereich werden dem Mitarbeiter per PDF-Datei die Arbeitsschritte angezeigt. Nachdem der Mitarbeiter die Bauteile seines Arbeitsplatzes eingebaut hat, scannt er einen auf diesen aufgedruckten Data-Matrix-Code. Im Panel möchte ich ihm nun anzeigen, welches Bauteil er abscannen soll und ob der vorherige Scan gültig war oder ob er die Reihenfolge vertauscht hat.

Gruß Fred78 :-)[/code]
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Mittwoch 18. März 2009, 22:57

Du verbindest dich zum Socket und lässt einen Listener in einer Endlosschleife als Thread laufen.

Dazu musst du dich also einmal verbinden und dann etwa so etwas hier in einem `while True` laufen lassen:

Code: Alles auswählen

while True:
    sock,addr = s.accept()
    l = sock.recv(1024)
    if l:
        #foo bar
Ich weiß nicht genau, wie das aussehen muss, da ich mich noch nie mit Threaded-Socket-Server-Zeugs auseinandergesetzt habe.
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Donnerstag 19. März 2009, 14:35

Wobei man keinesfalls einen Thread erstellen *muss*. Ich mag da insbesondere mal `gobject.io_add_watch()` erwähnen.
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
Antworten