return Variable eines Buttoncommands in Entry nutzen

Fragen zu Tkinter.
Antworten
Brüggz
User
Beiträge: 3
Registriert: Dienstag 30. Juni 2009, 10:21

Servus,

ich hab ein Fenster mit Entry, Button und Textfeld. Wenn ich den Loadbutton drücke und eine Datei anwähle, soll er mir den Dateipfad ins Entry schreiben. Ich weiß, dass man das mit Klassen hinkriegt, aber ich wollt darauf eigentlich verzichten. Nebenbei weiß ich auch nicht, warum das Dateifenster schon beim Start kommt und nicht erst beim Button drücken.

(filepath enthält nicht nur den Pfad, aber das mach ich später, mir gehts erstmal um die Variablenübergabe).

Code: Alles auswählen

from Tkinter import *
from tkFileDialog import askopenfile

wwidth=300
wheight=300


def load():
    file=askopenfile(mode='r')
    filepath = str(file)
    return filepath

app = Tk()


topframe = Frame(width=wwidth, height=wheight/10)
topframe.pack()
botframe = Frame(width=wwidth, height=wheight/10*9)
botframe.pack()

btnLoad = Button(app, text="Load nuke file!", command=load())
btnLoad.pack()
btnLoad.place(x=375, y=2)

namefield = Entry(app, text="test", width=60)
namefield.insert(END,"hi")      ### anstelle von "hi" soll hier der Dateipfad stehen
namefield.pack()
namefield.place(x=5, y=2)

app.columnconfigure(0, weight=5)
app.columnconfigure(1, weight=1)

infofield = Text(botframe)
infofield.pack()

app.protocol("WM_DELETE_WINDOW", app.quit)
app.mainloop()
app.destroy()
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Dazu musst der load-Funktion das Entry übergeben. Dazu kannst du entweder lambda benutzen, oder die "partial"-Funktion aus dem "functools"-Modul. Besser ist aber, wenn du auf ein objekt-orientiertes System umsteigst.

Die Funktion wird beim Erzeugen des Buttons aufgerufen, da du sie ausführst: "command=load()". Richtig muss es heißen "command=load". Damit übergibst du die Funktion und nicht deren Rückgabewert.

Noch ein paar Tips zum Code:
- mache keine *-Import, greife besser qualifiziert auf die Namen zu "Tkinter.Entry" oder schreibe "import Tkinter as tk" und dann qualifiziert mittels "tk.Entry".
- Wirf einen Blick auf PEP 8 (Konstanten, Leerzeichen, Namen)
- "file" solltest du nicht als Namen verwenden, da du damit einen built-in-Namen überdeckst.
Das Leben ist wie ein Tennisball.
BlackJack

@Brüggz: Zusätzlich zu den Anmerkungen von EyDu: Am besten keinen Programmcode auf Modulebene, ausser Importen, Funktions-, Klassen-, und Konstantendefinitionen. Dann kommt man gar nicht erst in Versuchung mit Modulglobalen, veränderlichen Objekten zu arbeiten.

Das jeweils übergeordnete Widget auch wirklich immer beim erzeugen eines neuen Widgets angeben.

Nicht verschiedene Layoutmanager in einem Container-Widget mischen und nicht `place()` verwenden.

Die beiden Zeilen vor und nach dem Aufruf der Tk-Hauptschleife sollten überflüssig sein.
Brüggz
User
Beiträge: 3
Registriert: Dienstag 30. Juni 2009, 10:21

EyDu hat geschrieben:Dazu musst der load-Funktion das Entry übergeben. Dazu kannst du entweder lambda benutzen, oder die "partial"-Funktion aus dem "functools"-Modul. Besser ist aber, wenn du auf ein objekt-orientiertes System umsteigst.
Danke für die Tipps, ich habs übrigens ganz anders gelöst, einfach in der load Funktion dem Entry den Dateinamen per INSERT zugewiesen :)

@BlackJack, mit versch. Layoutmanager meinst du die beiden Frames? Da hab ich eh nicht ganz durchgesehen und wie sollte ich das die 3 Elemente anordnen, ohne place? Wäre dankbar für etwas Code ;)
Also oben links soll das Entry, ziemlich breit. Rechts daneben der Load Button. Unten dann das Textfeld.

Danke.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Brüggz hat geschrieben:Danke für die Tipps, ich habs übrigens ganz anders gelöst, einfach in der load Funktion dem Entry den Dateinamen per INSERT zugewiesen :)
So sollst du es auch machen. Wenn du meine Hinweise nicht befolgt hast, dann ist das Entry-Feld bei dir wahrscheinlich eine globale Variable, was äußerst schlechtes Vorgehen ist. Daher mein Hinweise zu den Klassen oder wenigstens Parametern.
Brüggz hat geschrieben:@BlackJack, mit versch. Layoutmanager meinst du die beiden Frames? Da hab ich eh nicht ganz durchgesehen und wie sollte ich das die 3 Elemente anordnen, ohne place? Wäre dankbar für etwas Code ;)
Also oben links soll das Entry, ziemlich breit. Rechts daneben der Load Button. Unten dann das Textfeld.
Du sollst nicht "place" und "pack" zusammen verwenden, da dies zwei verschiedene Layout-Manager sind. Vergiss am besten, dass es place gibt, das sieht nur auf deinem System so aus, wie du es haben möchtest. Das Stichwort für dein Vorhaben ist der Layout-Manager grid.
Das Leben ist wie ein Tennisball.
BlackJack

@Brüggz: Mit Layoutmanagern meine ich `pack()`, `place()`, und `grid()`. Die wirfst Du alle munter durcheinander. Vom `grid()` verwdnest Du `columnconfigure()` was ohne `grid()` nicht viel Sinn macht. Einen der beiden `Frame`\s verwendest Du gar nicht, in den anderen steckst Du nur ein einziges anderes Widget. Das ist alles ziemlich sinnlos und durcheinander.

Der Grund warum `place()` ungünstig ist:

Bild
busfahrer
User
Beiträge: 111
Registriert: Donnerstag 9. Oktober 2008, 17:42

@Brüggz:So ungefähr sollte das zustande kommen was du gerne hättest.
Eventuelles Finetuning kannst du ja selbst betreiben

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf8 -*-


import Tkinter as tk

root = tk.Tk()
frame = tk.Frame(root)
frame.grid()
entry = tk.Entry(frame, bg="white")
entry.grid(row=0, column=0, ipadx=150)
button = tk.Button(frame, text="Load nuke File!")
button.grid(row=0, column=1)
text = tk.Text(frame, bg="white")
text.grid(row=1, column=0, columnspan=2)

root.mainloop()
Gruß...busfahrer
Alles wird gut ;-)
Brüggz
User
Beiträge: 3
Registriert: Dienstag 30. Juni 2009, 10:21

Sehr gut, danke. Ich seh bei den englischen docstrings von den tk-sachen wenig durch. Und in den Tutorials/ TKinter Anleitungen werden solche Sachen irgendwie net ausführlich erklärt.

Ich glaub das columnfigure hab ich vergessen rauszunehmen, in dem ganzen rumgeteste ;)
busfahrer
User
Beiträge: 111
Registriert: Donnerstag 9. Oktober 2008, 17:42

@Brüggz:Falls du es noch nicht kennst,hier noch etwas Lektüre zum
Grid Geometry Manager > http://effbot.org/tkinterbook/grid.htm

Gruß...busfahrer
Alles wird gut ;-)
Antworten