Werte aus einem Entry Widget (Tkinter) auslesen...

Fragen zu Tkinter.
Antworten
Crady
User
Beiträge: 18
Registriert: Freitag 31. Oktober 2008, 18:58

Sonntag 9. November 2008, 06:08

Hallo, zusammen!

wieder einmal habe ich ein (für mich) großes Problem:

Ich habe mit Tkinter eine GUI Klasse erstellt, in der ich 3 entry felder habe und einen Button.

Ich möchte nun Werte in diese 3 Entryfelder eingeben und wenn ich auf den Button klicke wird mittels commad=self.xxx eine funktion innerhalb dieser Klasse ausgeführt um die 3 Werte Variaben zuzuweisen, die ich dann gerne außerhalb der Klasse nutzen möchte...

Doch ich bekomme es einfach nicht hin, diese 3 Variablen außerhalb der Klasse zu verwenden...

Könnte mir da bitte jemand einen Denkanstoß geben? Ich habe schon klasse.variable ohne Erfolg versucht...

Danke!
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Sonntag 9. November 2008, 07:33

Ich könnte jetzt eben den fertigen Code schreiben, aber eigentlich will ich das nicht. Zeig am besten den konkreten Code(teil), dann wird dir schnell geholfen werden können.

Nur so viel:
Wenn du auf Modulebene ein Instanz mein_objekt der Klasse MeineKlasse mittels

Code: Alles auswählen

mein_objekt = MeineKlasse()
gebildet hast, dann kannst du selbstverständlich über mein_objekt.wert auch auf das Instanzattribut wert zugreifen (sofern es existiert und ihm zuvor der Inhalt des Entry-Feldes zugewiesen wurde).
BlackJack

Sonntag 9. November 2008, 08:40

Wobei man das IMHO auf Modulebene nicht machen sollte. Dann wird schnell aus Exemplaren auf hart kodierte Modulglobale zugegriffen und man hätte sich die Klassen auch sparen können.
Crady
User
Beiträge: 18
Registriert: Freitag 31. Oktober 2008, 18:58

Sonntag 9. November 2008, 14:09

Danke für die Antworten... hier der Code, um den es geht:

Code: Alles auswählen

def funktion():
      print app.eingabe1
      print app.eingabe2
      print app.eingabe3
      
      
      
from Tkinter import *

class gui:
  
  def __init__(self):
    master = Tk()
    
    master.title('Titel')
    
    self.label = Label(master,text='Label',
                       fg='red',
                       bg='white',
                       bd=5,
                       pady=4,
                       padx=4,
                       font=('Courier New',18,'bold underline'))
    self.label.pack()
                       
    self.e1txt = Message(master,width = 250, text='Eingabe1:')
    self.e1txt.pack(side=LEFT)
    
    self.entry1 = Entry(master)
    self.entry1.pack(side=LEFT)
    
    self.e2txt = Message(master,width = 250, text='Eingabe2:')
    self.e2txt.pack(side=LEFT)
    
    self.entry2 = Entry(master)
    self.entry2.pack(side=LEFT)
    
    self.e3txt = Message(master,width = 250, text='Eingabe3:')
    self.e3txt.pack(side=LEFT)
    
    self.entry3 = Entry(master)
    self.entry3.pack(side=LEFT)

    banButton = Button(master,text='OK', width = 10,command=self.ok)
    banButton.pack(side=LEFT)
            
    exitButton = Button(master,text='EXIT', height = 3, width = 10, command=master.destroy)
    exitButton.pack(side=TOP)                   
     
    master.mainloop()
      
  def ok(self):
    eingab1 = self.entry1.get()
    eingab2 = self.entry2.get()
    eingab3 = self.entry3.get()
    funktion()  
           
         
app = gui()
BlackJack

Sonntag 9. November 2008, 14:51

Wenn Du auf `app.eingabe1` zugeifen willst, solltest Du halt auch dafür sorgen dass es dieses Attribut gibt, und nicht einfach nur als lokalen Namen in einer Funktion.

Und genau so etwas ähnliches mit `app` auf Modulebene hatte ich befürchtet. Es ist unsauber auf globalen Werten zu operieren, die keine Konstanten sind. Werte sollten Funktionen als Argumente betreten und als Rückgabewerte verlassen.

Du könntest die Funktion zum Beispiel so aufrufen:

Code: Alles auswählen

def funktion(a, b, c):
    print a
    print b
    print c

# ...
    def ok(self):
        funktion(self.entry1.get(), self.entry2.get(), self.entry3.get())
Dann sollte die Klasse nach den üblichen Konventionen `Gui` heissen. Und Sternchen-Importe sind Böse™.

Innerhalb eines Widgets sollte man mit `pack()` nur eine Richtung für `side` verwenden, sonst kommt's schnell zu Chaos in der Anzeige.
Crady
User
Beiträge: 18
Registriert: Freitag 31. Oktober 2008, 18:58

Sonntag 9. November 2008, 18:17

BlackJack,

VIELEN DANK für Deine Hilfe :)

Ja, ich denke mir, dass meine Programmierung recht unsauber ist :(

aber nach einigem probieren (und leider auch weglassen der Klasse - das GUI wird nun direkt im Hauptprogramm gebiltet) funktioniert die ganze Anwendung so wie ich mir das vorstelle :)

Bei meinen nächsten Ideen und Umsetzungsversuchen werde ich bestimmt um einiges sauberer sein :oops:

Aber hier nun mal der ganze Code:

Mit diesem Programm ist es für Teams des Spiels LFS möglich, einen ban (oder unban) mit einem Klick für mehrere Server auf einmal auszuführen, ohne sich mit jedem einzelnen Server verbinden zu müssen.


Code: Alles auswählen

#

import threading
import Pyinsim
import sys


# Init globals
insim = Pyinsim.InSim(Pyinsim.INSIM_TCP)
connections = {}
players = {}
Action = ''
banaction = ''
Adminpass = ''

# Store hosts and ports as a dictionary (dict).
hosts = {29999: '127.0.0.1', 29998: '127.0.0.1', 29997: '192.168.2.104', 29996: '192.168.2.104'}


# Create a list to store each InSim connection.
sockets = []

# Helper functions.
def SendMessage(msg):
    """Send message to LFS."""
    if len(msg) > 64:
        socket.SendP(Pyinsim.Packet(Pyinsim.ISP_MSX, Msg=msg))
    else:
        socket.SendP(Pyinsim.Packet(Pyinsim.ISP_MST, Msg=msg))

# Connection lost.
def ConnectionLost():
    print 'InSim connection lost.'
    sys.exit(0)

insim.ConnectionLost(ConnectionLost)

#Timer function to close InSim client
def timer_close():
    for socket in sockets:
        socket.Close()

#Setting ban variables from GUI                    
def ban():
  global Adminpass
  Adminpass = adminpass.get()
  global Action
  Action = 'ban'
  UName = lname.get()
  if duration.get() == '':
     banduration = '1'
  else:
     banduration = duration.get()
  global banaction
  banaction = UName + ' ' + banduration     
  master.destroy()
          
#Setting unban variables from GUI
def unban():
    global Adminpass
    Adminpass = adminpass.get()
    global Action
    Action = 'unban'
    global banaction
    banaction = lname.get()
    master.destroy()
          
#Tkinter GUI
from Tkinter import *

master = Tk()
    
master.title('ban/unban tool')
    
label = Label(master, text='ban/unban tool',
                      fg='red',
                      bg='white',
                      bd=5,
                      pady=4,
                      padx=4,
                      font=('Courier New',18,'bold underline'))
label.pack()
                       
adtxt = Message(master, width = 250, 
                        text='Admin Pass:')
adtxt.pack(side=LEFT)
    
adminpass = Entry(master)
adminpass.pack(side=LEFT)
    
lntxt = Message(master, width = 250, 
                        text='Licence name:')
lntxt.pack(side=LEFT)
    
lname = Entry(master)
lname.pack(side=LEFT)
    
dutxt = Message(master, width = 250, 
                        text='Duration:')
dutxt.pack(side=LEFT)
    
duration = Entry(master)
duration.pack(side=LEFT)

banButton = Button(master, text='BAN', 
                           width = 10,
                           command=ban)
banButton.pack(side=LEFT)
    
unbanButton = Button(master, text='UNBAN', 
                             width = 10,
                             command=unban)
unbanButton.pack(side=LEFT)
   
exitButton = Button(master, text='EXIT', 
                            height = 3, 
                            width = 10, 
                            command=master.destroy)
exitButton.pack(side=TOP)                   
    
master.mainloop()
                         

# Loop over the hosts dictionary.
for port, host in hosts.iteritems():

    # Create new InSim object.
    insim = Pyinsim.InSim()

    # Connect to this server.
    insim.Connect(host, port)

    # Add connected InSim object to our sockets list.
    sockets.append(insim)
    

# Loop over the sockets 
for socket in sockets:
  if socket.Connected == True:
      print '/' + Action + ' ' + banaction + ' executed'        
      socket.SendP(Pyinsim.Packet(Pyinsim.ISP_ISI, Admin=Adminpass,
                                  IName='^3bantool', ReqI=1))
      SendMessage('/' + Action + ' ' + banaction)       
     
# Start timer.
timer = threading.Timer(15, timer_close)
timer.start()

# END OF PROGRAM
for socket in sockets:
    socket.Run()
      
Antworten