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!
Werte aus einem Entry Widget (Tkinter) auslesen...
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
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).
Nur so viel:
Wenn du auf Modulebene ein Instanz mein_objekt der Klasse MeineKlasse mittels
Code: Alles auswählen
mein_objekt = MeineKlasse()
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.
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()
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:
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.
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())
Innerhalb eines Widgets sollte man mit `pack()` nur eine Richtung für `side` verwenden, sonst kommt's schnell zu Chaos in der Anzeige.
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
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.
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

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()