Hallo zusammen,
wenn ich mitleidig lächelnde Gesichter erzeuge, ich habe fogendes Problem:
In dem angezeigten Fenster befinden sich 2 Buttons
Button 1
1.) Über einen File open Dialog wähle ich eine Datei aus.Der Dateiname wir in der Variable "filename" gespeichert.
2.)Der Inhalt der Variable wird in einer Message-Box angezeigt.
Button 2 soll nun den Inhalt der Datei in einer Message-Box anzeigen.
Ich(Python-Newbie) kriege es einfach nicht hin. Schäm!
Datei-Inhalt ausgeben
Es gibt mehr als ein Grafik GUI Framework welches verwendest du?
Außerdem ist die Messagebox eigentlich für kurze Nachrichten gedacht, wenn du den Inhalt einer Datei ausgeben willst, solltest du ein neues Fenster mit einer Textbox bauen.
Last but not least, das Forum ist kein wir übernehmen deine (Haus)aufgaben, wünsch dir was, sondern eine Hilfe zur Selbsthilfe und die meist auch sehr engagiert.
Also was hast du versucht, was ist der genaue Fehler, kannst du uns vielleicht einen minimalen Code (in Code tags) zeigen, mit den wir nachvollziehen können, woran du scheiterst?
Außerdem ist die Messagebox eigentlich für kurze Nachrichten gedacht, wenn du den Inhalt einer Datei ausgeben willst, solltest du ein neues Fenster mit einer Textbox bauen.
Last but not least, das Forum ist kein wir übernehmen deine (Haus)aufgaben, wünsch dir was, sondern eine Hilfe zur Selbsthilfe und die meist auch sehr engagiert.
Also was hast du versucht, was ist der genaue Fehler, kannst du uns vielleicht einen minimalen Code (in Code tags) zeigen, mit den wir nachvollziehen können, woran du scheiterst?
Hallo,
zuerst maldanke für die schnelle Antwort.
Hier mein letzter Stand:
code {
# -*- coding: iso-8859-1 -*-
import os
from fileinput import close, filename
from tabnanny import filename_only
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog as fd
from tkinter.messagebox import showinfo
# create the root window
root = tk.Tk()
root.title('Tkinter Open File Dialog')
root.resizable(False, False)
root.geometry('300x150')
def select_file():
filetypes = (
('text files', '*.txt'),
('All files', '*.*')
)
filename = fd.askopenfilename(
title='Datei öffnen',
initialdir='/',
filetypes=filetypes)
filename_2 = filename
showinfo(
title='Gewählte Datei',
message=filename
)
def print_file():
open (filename_2)
#print filename
close (filename_2)
# open button
open_button = ttk.Button(
root,
text='Datei öffnen',
command=select_file
)
open_button.pack(expand=True)
filename2 = (r"filename")
# open button2
open_button2 = ttk.Button(
root,
text='Datei öffnen2',
#command=print (filename2)
#datei = open(filename2,'r')
#command=print (r"filename")
#print(datei.read())
command = print_file()
)
open_button2.pack(expand=True)
# run the application
root.mainloop()
}
Zu
"Last but not least, das Forum ist kein wir übernehmen deine (Haus)aufgaben, wünsch dir was, sondern eine Hilfe zur Selbsthilfe und die meist auch sehr engagiert.
Bevor ich in Rente ging, habe ich jahrelang Visual C# programmiert (auch SQL- Datenbanken). Mein Sohn und mein Neffe befassen sich mit Python. Deshalb interessiere ich mich dafür.
Die Zeit der Hausaufgaben ist um.
Gruß,
Havefun
zuerst maldanke für die schnelle Antwort.
Hier mein letzter Stand:
code {
# -*- coding: iso-8859-1 -*-
import os
from fileinput import close, filename
from tabnanny import filename_only
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog as fd
from tkinter.messagebox import showinfo
# create the root window
root = tk.Tk()
root.title('Tkinter Open File Dialog')
root.resizable(False, False)
root.geometry('300x150')
def select_file():
filetypes = (
('text files', '*.txt'),
('All files', '*.*')
)
filename = fd.askopenfilename(
title='Datei öffnen',
initialdir='/',
filetypes=filetypes)
filename_2 = filename
showinfo(
title='Gewählte Datei',
message=filename
)
def print_file():
open (filename_2)
#print filename
close (filename_2)
# open button
open_button = ttk.Button(
root,
text='Datei öffnen',
command=select_file
)
open_button.pack(expand=True)
filename2 = (r"filename")
# open button2
open_button2 = ttk.Button(
root,
text='Datei öffnen2',
#command=print (filename2)
#datei = open(filename2,'r')
#command=print (r"filename")
#print(datei.read())
command = print_file()
)
open_button2.pack(expand=True)
# run the application
root.mainloop()
}
Zu
"Last but not least, das Forum ist kein wir übernehmen deine (Haus)aufgaben, wünsch dir was, sondern eine Hilfe zur Selbsthilfe und die meist auch sehr engagiert.
Bevor ich in Rente ging, habe ich jahrelang Visual C# programmiert (auch SQL- Datenbanken). Mein Sohn und mein Neffe befassen sich mit Python. Deshalb interessiere ich mich dafür.
Die Zeit der Hausaufgaben ist um.
Gruß,
Havefun
Das mit den codetag hat leder nicht geklappt.
Das import os wird nicht verwendet und meistens sollte man bei Path Operationen auch besser die Pathlib verwenden.
Dein Hauptproblem ist, das du einmal ein filename2 als globale variable hast und an diversen stellen filename_2 als Lokale variablen.
Außerdem würde die Zuweisung von filename_2 in der Funktion select_file die globale Variable überlagern da musst du mit den global Keyword arbeiten. Generell in Python sollten globale Variablen großgeschrieben werden.
Hier mal eine leicht verbesserte Version deines Programms.
Das import os wird nicht verwendet und meistens sollte man bei Path Operationen auch besser die Pathlib verwenden.
Dein Hauptproblem ist, das du einmal ein filename2 als globale variable hast und an diversen stellen filename_2 als Lokale variablen.
Außerdem würde die Zuweisung von filename_2 in der Funktion select_file die globale Variable überlagern da musst du mit den global Keyword arbeiten. Generell in Python sollten globale Variablen großgeschrieben werden.
Hier mal eine leicht verbesserte Version deines Programms.
Code: Alles auswählen
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.filedialog as filedialog
import tkinter.messagebox as messagebox
from pathlib import Path
FILENAME = ""
def select_file():
global FILENAME
filetypes = (
('text files', '*.txt'),
('All files', '*.*')
)
FILENAME = filedialog.askopenfilename(
title='Datei öffnen',
initialdir=Path.home().as_posix(),
filetypes=filetypes
)
def show_file(root):
new_window = tk.Toplevel(root)
new_window.title(FILENAME)
menu = tk.Menu(new_window)
new_window.config(menu=menu)
file_menu = tk.Menu(menu)
file_menu.add_command(label="Exit", command=new_window.destroy)
menu.add_cascade(label="Datei", menu=file_menu)
textbox = tk.Text(new_window)
textbox.pack(expand=True)
try:
with open(FILENAME, "r", encoding="utf-8") as inp:
textbox.insert(tk.END, inp.read())
except IOError:
new_window.destroy()
messagebox.showwarning(
title="Datei Fehler",
message=f"Die Datei {FILENAME} kann nicht geöffnet werden",
)
def open_dialog():
root = tk.Tk()
root.title('Tkinter Open File Dialog')
root.resizable(False, False)
root.geometry('300x150')
file_select_button = ttk.Button(
root,
text='Datei öffnen',
command=select_file
)
file_view_button = ttk.Button(
root,
text="Datei anzeigen",
command=lambda: show_file(root)
)
file_select_button.pack(expand=True)
file_view_button.pack(expand=True)
return root
def main():
root = open_dialog()
root.mainloop()
if __name__ == '__main__':
main()
- __blackjack__
- User
- Beiträge: 13919
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@imonbln: Hier würde ich mal ganz stark widersprechen: Globale Variablen sollte es gar nicht geben, aber wenn dann auf gar keinen Fall KOMPLETT_GROSS geschrieben, denn das ist dann ja *noch* schlechter, weil man dann mit der Erwartung bricht, dass alles was KOMPLETT_GROSS geschrieben ist, eine *Konstante* ist, und keine Variable.
``as`` beim Import ist drei mal falsch verwendet, weil da nix umbenannt wird.
Warum steht in der `main()` fast nix drin? Die `open_dialog()` sollte da inhaltlich drin stehen.
@havefun: Fenstergrössen gibt man nicht hart in Pixeln vor. Das sollte man noch nie, weil das schon immer nicht funktioniert hat, aber heutzutage bei dem Zoo von Displaygrössen und -auflösungen, und -einstellungen geht das echt gar nicht mehr. Die Fenstergrösse ergibt sich automatisch aus dem Inhalt.
„Datei öffnen“ ist für beide Schaltflächen als Text inhaltlich nicht richtig. Mit der einen wählt man eine Datei aus, mit der anderen wird sie angezeigt.
Das Programm sollte den Fall berücksichtigen, das der Benutzer keine Datei ausgewählt hat. Entweder beim Anzeigen, oder in dem man die Schaltfläche zum Anzeigen solange deaktiviert bis der Benutzer eine Datei ausgewählt hat. Also erst prüfen ob eine Datei ausgewählt wurde, dann die Datei einlesen, mit Fehlerausgabe wenn das nicht funktioniert, und dann erst die Anzeige.
Ungetestet:
Ganz allgemein kann man zu GUIs sagen, dass man bei jeder nicht-trivialen GUI nicht um objektorientierte Programmierung herum kommt, also man muss dafür eigene Klassen schreiben können. Nur bei sehr einfachen Sachen kommt man noch mit Closures aus. In diesem Beispiel hier konkret hat man noch Glück, dass ``tkinter`` die Tcl-Variablen in Objekte verpackt, weil man das braucht wenn man ”Listener” dafür registrieren will, weil in Tcl jede Variable ein ”Observable” ist, um das mal in Entwurfsmustern zu formulieren. Und das man maximal zwei Werte bei den Aufrufen weiter-/durchreichen muss.
Der Hinweis bezieht sich nicht nur auf Schule/Studium/Ausbildung und Hausaufgaben, sondern ganz allgemein. Zumal wir das ja auch alles nicht nachprüfen können, ob das hilflose nette Mädchen nicht nur Typ ist der denkt die Computernerds würden sich darum reissen ”ihr” bei den Hausaufgaben zu ”helfen”. Es ist manchmal erstaunlich wie viel Zeit und Energie manche Leute da rein stecken sich Komplettlösungen zu erbetteln, wo sie in weniger Zeit und mit weniger Energie die Aufgabe dreimal hätten selbst lösen können.
Das ist nicht gegen Dich persönlich gerichtet, man hat halt so seine Erfahrungen, und ist entsprechend misstrauisch wenn Eltern oder Grosseltern mit Aufgaben der Kinder oder Enkelkinder hier nach Lösungen fragen.
``as`` beim Import ist drei mal falsch verwendet, weil da nix umbenannt wird.
Warum steht in der `main()` fast nix drin? Die `open_dialog()` sollte da inhaltlich drin stehen.
@havefun: Fenstergrössen gibt man nicht hart in Pixeln vor. Das sollte man noch nie, weil das schon immer nicht funktioniert hat, aber heutzutage bei dem Zoo von Displaygrössen und -auflösungen, und -einstellungen geht das echt gar nicht mehr. Die Fenstergrösse ergibt sich automatisch aus dem Inhalt.
„Datei öffnen“ ist für beide Schaltflächen als Text inhaltlich nicht richtig. Mit der einen wählt man eine Datei aus, mit der anderen wird sie angezeigt.
Das Programm sollte den Fall berücksichtigen, das der Benutzer keine Datei ausgewählt hat. Entweder beim Anzeigen, oder in dem man die Schaltfläche zum Anzeigen solange deaktiviert bis der Benutzer eine Datei ausgewählt hat. Also erst prüfen ob eine Datei ausgewählt wurde, dann die Datei einlesen, mit Fehlerausgabe wenn das nicht funktioniert, und dann erst die Anzeige.
Ungetestet:
Code: Alles auswählen
#!/usr/bin/env python3
import tkinter as tk
from pathlib import Path
from tkinter import filedialog, messagebox, ttk
def select_file(filename_var):
filename_var.set(
filedialog.askopenfilename(
title="Datei öffnen",
initialdir=Path.home().absolute(),
filetypes=(("text files", "*.txt"), ("All files", "*.*")),
)
)
def show_file(master, filename_var):
filename = filename_var.get()
if filename:
try:
content = Path(filename).read_text(encoding="utf-8")
except IOError as error:
messagebox.showerror(
"E/A-Fehler",
f"Die Datei {filename} konnte nicht gelesen werden.\n{error}",
)
else:
window = tk.Toplevel(master)
window.title(filename)
menu = tk.Menu(window)
window.config(menu=menu)
file_menu = tk.Menu(menu)
file_menu.add_command(label="Exit", command=window.destroy)
menu.add_cascade(label="Datei", menu=file_menu)
textbox = tk.Text(window)
textbox.pack(expand=True)
textbox.insert(tk.END, content)
else:
messagebox.showerror(
"Keine Datei gewählt",
"Es muss eine Datei zur Anzeige ausgewählt werden!",
)
def main():
root = tk.Tk()
root.title("Tkinter Open File Dialog")
root.resizable(False, False)
filename_var = tk.StringVar(value="")
ttk.Button(
root, text="Datei auswählen", command=lambda: select_file(filename_var)
).pack(expand=True)
ttk.Button(
root,
text="Datei anzeigen",
command=lambda: show_file(root, filename_var),
).pack(expand=True)
root.mainloop()
if __name__ == "__main__":
main()
Der Hinweis bezieht sich nicht nur auf Schule/Studium/Ausbildung und Hausaufgaben, sondern ganz allgemein. Zumal wir das ja auch alles nicht nachprüfen können, ob das hilflose nette Mädchen nicht nur Typ ist der denkt die Computernerds würden sich darum reissen ”ihr” bei den Hausaufgaben zu ”helfen”. Es ist manchmal erstaunlich wie viel Zeit und Energie manche Leute da rein stecken sich Komplettlösungen zu erbetteln, wo sie in weniger Zeit und mit weniger Energie die Aufgabe dreimal hätten selbst lösen können.
Das ist nicht gegen Dich persönlich gerichtet, man hat halt so seine Erfahrungen, und ist entsprechend misstrauisch wenn Eltern oder Grosseltern mit Aufgaben der Kinder oder Enkelkinder hier nach Lösungen fragen.
“I am Dyslexic of Borg, Your Ass will be Laminated” — unknown
Hallo,
@__blackjack__ ich habe mal wieder Fragen, die eine hatten wir ähnlich, kürzlich erst, welchen Mehrwert bringt `_var` in `filename_var`? Ich sehe dass das ein `StringVar` - Objekt ist und dadurch hat das andere Methoden als ein String. Ist dass der Grund oder gibt es noch einen?
Und wäre die Funktion so eventuell etwas schöner? Mein Gedanke war, ich sehe auf einen Blick was im `if`-Zweig passiert und es wird übersichtlicher, weil der Rest nicht eingerückt werden muss.
Danke und Grüße
Dennis
@__blackjack__ ich habe mal wieder Fragen, die eine hatten wir ähnlich, kürzlich erst, welchen Mehrwert bringt `_var` in `filename_var`? Ich sehe dass das ein `StringVar` - Objekt ist und dadurch hat das andere Methoden als ein String. Ist dass der Grund oder gibt es noch einen?
Und wäre die Funktion so eventuell etwas schöner? Mein Gedanke war, ich sehe auf einen Blick was im `if`-Zweig passiert und es wird übersichtlicher, weil der Rest nicht eingerückt werden muss.
Code: Alles auswählen
def show_file(master, filename_var):
filename = filename_var.get()
if not filename:
messagebox.showerror(
"Keine Datei gewählt",
"Es muss eine Datei zur Anzeige ausgewählt werden!",
)
return
try:
content = Path(filename).read_text(encoding="utf-8")
except IOError as error:
messagebox.showerror(
"E/A-Fehler",
f"Die Datei {filename} konnte nicht gelesen werden.\n{error}",
)
else:
window = tk.Toplevel(master)
window.title(filename)
menu = tk.Menu(window)
window.config(menu=menu)
file_menu = tk.Menu(menu)
file_menu.add_command(label="Exit", command=window.destroy)
menu.add_cascade(label="Datei", menu=file_menu)
textbox = tk.Text(window)
textbox.pack(expand=True)
textbox.insert(tk.END, content)
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
- __blackjack__
- User
- Beiträge: 13919
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@havefun: Da Du nichts über mich geschrieben hast, kann ich das ja auch nicht persönlich nehmen.
“I am Dyslexic of Borg, Your Ass will be Laminated” — unknown
- __blackjack__
- User
- Beiträge: 13919
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Dennis89: Genau das war die Idee hinter dem `*_var`, damit man nicht denkt, dass es direkt ein Dateiname ist und von Zeichenkette oder `Path`-Objekt ausgeht. Insbesondere in der `show_file()`-Funktion haben wir dann ja auch beides: `filename` und `filename_var`. Spätestens an der Stelle hätte man sonst ja auch das Problem wie man `filename` nennen soll, wenn das schon für das `StringVar`-Objekt steht.
Das mit dem „early return“ finde ich persönlich nicht schöner. So tief verschachtelt war das ja noch nicht. Und wenn, dann hätte ich wahrscheinlich auch eher dazu tendiert etwas in eine eigene Funktion auszulagern. Auf der anderen Seite hätte ich da aber auch keinen Drang das umzuschreiben, wenn ich das in Code so vorfinden würde. Am Anfang einer Funktion Randfälle abfragen und vorzeitig abbrechen ist nicht ungewöhnlich.
Das mit dem „early return“ finde ich persönlich nicht schöner. So tief verschachtelt war das ja noch nicht. Und wenn, dann hätte ich wahrscheinlich auch eher dazu tendiert etwas in eine eigene Funktion auszulagern. Auf der anderen Seite hätte ich da aber auch keinen Drang das umzuschreiben, wenn ich das in Code so vorfinden würde. Am Anfang einer Funktion Randfälle abfragen und vorzeitig abbrechen ist nicht ungewöhnlich.
“I am Dyslexic of Borg, Your Ass will be Laminated” — unknown