TCP Chat für alle Formulare

Fragen zu Tkinter.
Antworten
schnibli
User
Beiträge: 27
Registriert: Mittwoch 19. November 2014, 18:52

Hallo zusammen,

Ich habe bis Heute immer nur mit einem Formular gearbeitet, da war der Tcp Chat kein Problem:

Code: Alles auswählen

TCP_IP = '192.168.61.91'
TCP_PORT = 8052
BUFFER_SIZE = 1024
MESSAGE = "Hello, World!"
   
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(bytes("1234", "utf-8"))
data = s.recv(BUFFER_SIZE)
s.close()
   
print ("received data:"), data
Nun habe ich mehrere Formulare und möchte den Clienten in allen Formularen verwenden, wie kann ich das anstellen?

Code: Alles auswählen

try:
    import tkinter as tk
except:
    import Tkinter as tk
import sys
import socket
import tkinter
import sys
from functools import partial
from tkinter import PhotoImage
 

 
class Kalender():
    def __init__(self, master):
        self.master=master
        self.frame = tk.Frame(self.master)
        self.de=PhotoImage(file='de.gif')
        self.ton_de_button = tk.Button(self.master, image=self.de, command = self.do_exit)
        self.exitbutton = tk.Button(self.master, text="Kalender Beenden", command=self.do_exit)
        self.ton_de_button.pack()
        self.exitbutton.pack()
 
    def do_exit(self):
        self.master.quit()
        self.master.destroy()
        print ("Buttons beendet!")
 
class Bilder():
    def __init__(self, master):
        self.master=master
        self.frame = tk.Frame(self.master)

        ##Play
        self.play=PhotoImage(file='play.gif')
        self.play_button = tk.Button(self.master, image=self.play, command = self.play_gewaehlt)
        ##Pause
        self.pause=PhotoImage(file='pause.gif')
        self.pause_button = tk.Button(self.master, image=self.pause, command = self.pause_gewaehlt)
        ##Vor
        self.vor=PhotoImage(file='vor.gif')
        self.vor_button = tk.Button(self.master, image=self.vor, command = self.vor_gewaehlt)
        ##Zurück
        self.zurueck=PhotoImage(file='zurueck.gif')
        self.zurueck_button = tk.Button(self.master, image=self.zurueck, command = self.zurueck_gewaehlt)
        ##Video Abspielen
        self.video_start=PhotoImage(file='film_abspielen.gif')
        self.video_start_button = tk.Button(self.master, image=self.video_start, command = self.video_start_gewaehlt)
        ##Video Stoppen
        self.video_stop=PhotoImage(file='film_stoppen.gif')
        self.video_stop_button = tk.Button(self.master, image=self.video_stop, command = self.video_stop_gewaehlt)
        ##Ton ein
        self.ton_ein=PhotoImage(file='ton_ein.gif')
        self.ton_ein_button = tk.Button(self.master, image=self.ton_ein, command = self.ton_ein_gewaehlt)
        ##Ton aus
        self.ton_aus=PhotoImage(file='ton_aus.gif')
        self.ton_aus_button = tk.Button(self.master, image=self.ton_aus, command = self.ton_aus_gewaehlt)
        ##Video Deutsch
        self.sprache_deutsch=PhotoImage(file='de.gif')
        self.sprache_deutsch_button = tk.Button(self.master, image=self.sprache_deutsch, command = self.sprache_deutsch_gewaehlt)
        ##Video Schweizerdeutsch
        self.sprache_sdeutsch=PhotoImage(file='sde.gif')
        self.sprache_sdeutsch_button = tk.Button(self.master, image=self.sprache_sdeutsch, command = self.sprache_sdeutsch_gewaehlt)
        ##Video Französisch
        self.sprache_franz=PhotoImage(file='fr.gif')
        self.sprache_franz_button = tk.Button(self.master, image=self.sprache_franz, command = self.sprache_franz_gewaehlt)

        ##Buttons erstellen
        self.exitbutton = tk.Button(self.master, text="Bilder Beenden", command = self.zurueck)
        self.play_button.pack()
        self.pause_button.pack()
        self.vor_button.pack()
        self.zurueck_button.pack()
        self.video_start_button.pack()
        self.video_stop_button.pack()
        self.ton_ein_button.pack()
        self.ton_aus_button.pack()
        self.sprache_deutsch_button.pack()
        self.sprache_sdeutsch_button.pack()
        self.sprache_franz_button.pack()
        self.exitbutton.pack()
 
    ##Play
    def play_gewaehlt(self):
        print("Button 1 gedrueckt")
    ##Pause
    def pause_gewaehlt(self):
        print("Button 1 gedrueckt")
    ##vor
    def vor_gewaehlt(self):
        print("Button 1 gedrueckt")
   ##Zurück
    def zurueck_gewaehlt(self):
        print("Button 1 gedrueckt")
    ##Video Starten
    def video_start_gewaehlt(self):
        print("Button 1 gedrueckt")
    ##Video Stoppen
    def video_stop_gewaehlt(self):
        print("Button 1 gedrueckt")
    ##Ton ein
    def ton_ein_gewaehlt(self):
        print("Button 1 gedrueckt")
    ##ton_aus
    def ton_aus_gewaehlt(self):
        print("Button 1 gedrueckt")
    ##sprache deutsch
    def sprache_deutsch_gewaehlt(self):
        print("Button 1 gedrueckt")
    ##sprache sdeutsch
    def sprache_sdeutsch_gewaehlt(self):
        print("Button 1 gedrueckt")
    ##sprache franz
    def sprache_franz_gewaehlt(self):
        print("Button 1 gedrueckt")




    ##schliessen
    def zurueck(self):
        self.master.quit()
        self.master.destroy()
        print ("Buttons beendet!")


        
class MainFrame():
 
    def __init__(self):
        
        
        self.root = tk.Tk()
        self.state('zoomed')
        

        ##start_class_button = tk.Button(self.root, text="Öffnen", command=self.do_start_class, width=20)
        

        ##Kalender öffnen 
        self.kalender=PhotoImage(file='kalender.gif')
        self.kalender_menu_button = tk.Button(self.root, image=self.kalender, command=self.kalender_modus)

        ##Präsentation öffnen
        self.praesentation=PhotoImage(file='praesentations_modus.gif')
        self.praesentations_modus_button = tk.Button(self.root, image=self.praesentation, command=self.praesentation_modus)

        ##Präsentation öffnen
        self.radio=PhotoImage(file='radios.gif')
        self.radio_button = tk.Button(self.root, image=self.radio, command=self.radio_modus)

        ##Beenden
        exit_button = tk.Button(self.root, text="beenden", command=self.do_exit, width=20)
        
        ##start_class_button.pack()
        
        self.kalender_menu_button.pack()
        self.praesentations_modus_button.pack()
        self.radio_button.pack()
        exit_button.pack()
        self.root.mainloop()
         
    def do_exit(self):
        self.root.quit()
        self.root.destroy()
 
 
    def kalender_modus(self):
        if self.state==False:
            print ("starte Subfenster...")
            self.buttons = Kalender(tk.Toplevel())
            self.state=True
        else:
            print ("schließe Subfenster...")
            self.state=False

    def radio_modus(self):
        if self.state==False:
            print ("starte Subfenster...")
            self.buttons = Kalender(tk.Toplevel())
 
            self.state=True
        else:
            print ("schließe Subfenster...")
            self.state=False

    def praesentation_modus(self):
        if self.state==False:
            print ("starte Subfenster...")
            self.buttons = Bilder(tk.Toplevel())
 
            self.state=True
        else:
            print ("schließe Subfenster...")
            self.state=False

            
myframe = MainFrame()
 
print ("Programm beendet")
BlackJack

@schnibli: Welcher Client? Und was hat der Kalendar mit Chat zu tun?

Was so beim drüberschauen auffällt: Im `MainFrame` wird in der `__init__()` eine `state()`-Methode aufgerufen, die es gar nicht gibt und in anderen Methoden wird dieses Attribut als Wahrheitswert behandelt, es wird in der `__init__()` aber gar nicht initialisiert.
schnibli
User
Beiträge: 27
Registriert: Mittwoch 19. November 2014, 18:52

Dies ist ein Programm für einen Raspberry pi mit Touchscreen,
Der über TCP mit einem Windows Computer komunitiert und diesem sagt was er tun soll.

Z.b. Raspberry sendet: "kalender_anzeigen"
Windows Computer zeigt den Kalender an


Früher machte ich dies so:

Code: Alles auswählen

from tkinter import *
from tkinter import ttk
import sys
import socket
import tkinter
## Deklaration Tk (Form)
root = Tk()
root.title("Präsentation")
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.overrideredirect(1)
root.geometry("%dx%d+0+0" % (w, h))
mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)
Kalender = "aus"
## Versuch TCP Client

TCP_IP = '192.168.61.91'
TCP_PORT = 8052
BUFFER_SIZE = 1024
MESSAGE = "Hello, World!"
   
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(bytes("1234", "utf-8"))
data = s.recv(BUFFER_SIZE)
s.close()
   
print ("received data:"), data
## Button Ereignisse
## Form (TK) schliessen
def close_window (): 
  root.destroy()
## Kalender Starten
def calendar_start ():
  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  s.connect((TCP_IP, TCP_PORT))
  s.send(bytes("calendar_start", "utf-8"))
  s.close()
(Dies ist nur einen Ausschnitt meines Codes)

Nur jetzt wo ich mehrere Formulare habe mit verschiedenen Buttons würde ich gerne einen Chat client haben, und von den verschiedenen Formularen Nachrichten versenden:
Das sollte irgendwie so aussehen nur das es so nicht funktioniert xD.....

Code: Alles auswählen

try:
    import tkinter as tk
except:
    import Tkinter as tk
import sys
import socket
import tkinter
import sys
from functools import partial
from tkinter import PhotoImage
 

TCP_IP = '192.168.61.91'
TCP_PORT = 8052
BUFFER_SIZE = 1024
MESSAGE = "Hello, World!"
   
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(bytes("1234", "utf-8"))
data = s.recv(BUFFER_SIZE)
s.close()

class FullScreenApp(object):
    def __init__(self, master, **kwargs):
        self.master=master
        pad=3
        self._geom='200x200+0+0'
        master.geometry("{0}x{1}+0+0".format(
            master.winfo_screenwidth()-pad, master.winfo_screenheight()-pad))
        master.bind('<Escape>',self.toggle_geom)            
    def toggle_geom(self,event):
        geom=self.master.winfo_geometry()
        print(geom,self._geom)
        self.master.geometry(self._geom)
        self._geom=geom
 
class Kalender():
    def __init__(self, master):
        self.master=master
        app=FullScreenApp(self.master)
        self.frame = tk.Frame(self.master)


        ## Kalender Anzeigen
        self.kalender_anzeigen=PhotoImage(file='kalender_anzeigen.gif')
        self.kalender_anzeigen_button = tk.Button(self.master, image=self.kalender_anzeigen, command = self.kalender_anzeigen_gewaehlt).grid(row=1,column=1,columnspan=8)

    ##Kalender anzeigen gewaehlt
    def kalender_anzeigen_gewaehlt(self):
         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         s.connect((TCP_IP, TCP_PORT))
         s.send(bytes("calendar_start", "utf-8"))
         s.close()
[/code]
(Dies ist nur einen Ausschnitt meines Codes)
Sirius3
User
Beiträge: 17740
Registriert: Sonntag 21. Oktober 2012, 17:20

@schnibli: "Funktioniert nicht" ist keine hilfreiche Fehlerbeschreibung. Niemand außer Dir, weiß, was wie tun soll und was das Programm wirklich macht. Was ich mir aus Deinen Beschreibungen zusammengereimt habe, ist, dass es irgendein TK-Fenster mit Knöpfen gibt, daneben ein selbst erfundenes TCP-Protokoll, das irgendwelche Befehle irgendwohin schickt.
Das sind zwei getrennte Dinge, die Du auch getrennt entwickeln solltest und testen. Also zuerst ein Modul schreiben, das Funktionen enthält um mit einem anderen Rechner zu kommunizieren. Diese Funktionen kannst Du zum Testen direkt aufrufen, um zu sehen, ob sie auch das machen, was Du erwartest.
Danach, wenn das alles tut, kannst Du mit der GUI anfangen, also Knöpfen, die die Funktionen aus dem Kommunikations-Modul aufrufen.
schnibli
User
Beiträge: 27
Registriert: Mittwoch 19. November 2014, 18:52

Also nochmal zu meinem Problem:

Ich starte den chat so:

Code: Alles auswählen

## Versuch TCP Client

TCP_IP = '192.168.61.91'
TCP_PORT = 8052
BUFFER_SIZE = 1024
MESSAGE = "Hello, World!"
   
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(bytes("1234", "utf-8"))
data = s.recv(BUFFER_SIZE)
s.close()
Möchte beim klick auf den Button eine Nachricht versenden (Dieser Button Funktioniert daher nur die auswärtung):

Code: Alles auswählen

##Kalender anzeigen gewaehlt
    def kalender_anzeigen_gewaehlt(self):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((TCP_IP, TCP_PORT))
        s.send(bytes("calendar_start", "utf-8"))
        s.close()
Leider wird die nachricht nicht versendet und es gibt auch keine Fehler Meldung...

Meine Frage,
Muss ich den Chat auch in eine Class einbinden oder wie muss ich das anstellen?d


Zum verständiss:

Ich habe verschiedene klassen (formulare)
In jeder Klasse (Formular) hat es Buttons.
Jeder Button soll über TCP Chat etwas senden.
Sirius3
User
Beiträge: 17740
Registriert: Sonntag 21. Oktober 2012, 17:20

@schnibli: um sicher zu sein, dass die komplette Nachricht gesendet wird, solltest Du `sendall` verwenden. Woher weißt Du, dass die Nachricht nicht versendet wird?
schnibli
User
Beiträge: 27
Registriert: Mittwoch 19. November 2014, 18:52

Du bist nicht schlecht :)
Die Nachricht kam an, jedoch war der Text falsch :)


Danke
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Hi schnibli,
schnibli hat geschrieben:Die Nachricht kam an, jedoch war der Text falsch :)
haha, heute ist lustige Ratestunde, was? Du machst es uns aber auch nicht leicht. :lol:

Ich fange mal an, also:
War der Inhalt komplett falsch/verstellt oder nur unvollständig?
Wie viele Zeichen hast Du zu versenden versucht und wie viele kamen an?
Bei welchen Nachrichten kam nicht das an, was Du schicken wolltest - hat es bei manchen Sendungen funktioniert?
Kannst Du ein Beispiel für eine ausgehende und eine empfangene Nachricht schreiben?

VG,
Sky
Diese Nachricht zersört sich in 5 Sekunden selbst ...
schnibli
User
Beiträge: 27
Registriert: Mittwoch 19. November 2014, 18:52

Hallo :)
Sorry sendall hat mir die Lösung gebracht, ich hab nicht verglichen was ankommt oder nicht.
als ich gemerkt habe, das der Text nicht richtig ankommt habe ich es mit "sendall" probiert und es Funktionierte.
Ich werde es nochmals auskommentieren und schauen was genau ankommt und was nicht.
Antworten