@Sirius3:
Danke für Deinen Hinweis. Genau so wie Du schreibst, hatte ich es und ich weiß, was dann alles nicht mehr geht und genau deshalb habe ich den Verweis auf die Klasse herausgenommen. Ansonsten müsste ich die alle Funktionsdefinitionen in den main-Block nehmen. Das wollte ich vermeiden, aber vermutlich ist es so doch richtig. Was sagst Du dazu?
MfG, kodela
Menübreite anpassen
@kodela: so ist es nicht richtig. Dass Du Probleme bekommst ist doch ein eindeutiges Zeichen dafür, dass da was noch nicht stimmt. Und wenn man Funktionen innerhalb von Funktionen definieren muß, dann zeigt das auch "hier stimmt was nicht". Die Lösung ist, all die Funktionen als Methoden der Klassse zu schreiben. Bei clear_text hast Du ja gezeigt, dass Du das kannst.
-
- User
- Beiträge: 185
- Registriert: Montag 12. Oktober 2015, 21:24
- Wohnort: Landsberg am Lech
- Kontaktdaten:
@Sirius3:
Wäre es dann so richtig?
MfG, kodela
Wäre es dann so richtig?
Code: Alles auswählen
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import Tkinter as tk
import webbrowser
class GUI_Interface:
def __init__(self, tk):
self.frame = tk.Tk()
self.frame.title('Erstes Fenster')
self.frame.geometry('300x130')
self.menu = tk.Menu(self.frame)
filemenu = tk.Menu(self.menu, tearoff=0)
filemenu.add_command(label='Öffnen . . .', \
accelerator='Strg+O', command=self.oeffnen)
filemenu.add_command(label='Speichern . . .', \
accelerator='Strg+S', command=self.speichern)
filemenu.add_command(label='Speichern unter . . .\t\t\t', \
accelerator='Strg+Shift+S', command=self.speichern_unter)
filemenu.add_separator()
filemenu.add_command(label='Beenden', \
accelerator='Strg+Q', command=self.frame.quit)
self.menu.add_cascade(label='Datei', menu=filemenu)
editmenu = tk.Menu(self.menu, tearoff=0)
editmenu.add_command(label='Forum öffnen', command=self.webpage)
editmenu.add_command(label='Pause', command=self.hallo)
editmenu.add_command(label='Einfügen', command=self.klick)
self.menu.add_cascade(label='Bearbeiten', menu=editmenu)
helpmenu = tk.Menu(self.menu, tearoff=0)
helpmenu.add_command(label='Über', command=self.hallo)
self.menu.add_cascade(label='Hilfe', menu=helpmenu)
self.frame.config(menu=self.menu)
self.panel = tk.Frame(self.frame)
self.eingabe = tk.Entry(self.panel)
self.eingabe.insert(0,'Hallo Welt!')
self.eingabe.pack(fill=tk.X, padx=15, pady=20)
self.b_clear = tk.Button(self.panel, text="Löschen",
width=12, height=1, command=self.clear_text)
self.b_clear.pack(side="left", padx=20, pady=10)
self.b_quit = tk.Button(self.panel, text="Beenden",
width=12, height=1, command=self.frame.quit)
self.b_quit.pack(side="right", padx=20, pady=10)
self.panel.pack(fill=tk.X)
def key(event):
# Umschalttasten (Groß/Klein-Ziffernblock) ausmaskieren
_state = event.state & 5
# nur Strg + Zeichentaste
if _state == 4:
if event.keysym.upper() == 'O':
self.oeffnen()
elif event.keysym.upper() == 'S':
self.speichern()
elif event.keysym.upper() == 'Q':
self.frame.destroy()
# Strg + Shift + Zeichentaste
elif _state == 5:
if event.keysym.upper() == 'S':
self.speichern_unter()
self.frame.bind('<Key>', key)
def clear_text(self):
self.eingabe.delete(0,tk.END)
def oeffnen(self):
self.eingabe.delete(0, tk.END)
self.eingabe.insert(0,'Es soll geöffnet werden.')
def speichern(self):
self.eingabe.delete(0, tk.END)
self.eingabe.insert(-1, 'Es soll gespeichert werden.')
def speichern_unter(self):
self.eingabe.delete(0, tk.END)
self.eingabe.insert(0, 'Es soll unter neuem Namen gespeichert werden.')
def hallo(self):
self.eingabe.delete(0, tk.END)
self.eingabe.insert(-1, 'Hallo!')
def klick(self):
self.eingabe.delete(0, tk.END)
self.eingabe.insert(-1, 'Das war ein Klick!')
def webpage(self):
self.eingabe.delete(0, tk.END)
self.eingabe.insert(-1, 'Python-Forum öffnen')
webbrowser.open("http://www.python-forum.de")
def main():
app = GUI_Interface(tk)
app.frame.mainloop()
if __name__ == '__main__':
main()
@kodela: Die `key()`-Funktion ist noch lokal in einer anderen Funktion/Methode definiert. Das würde ich noch ändern.
Und ich würde wahrscheinlich weiter abstrahieren, oder gleich ein richtiges GUI-Rahmenwerk verwenden bevor ich mir so etwas wie `QAction` oder `Gtk.Action` für Tk selber programmiere.
Und ich würde wahrscheinlich weiter abstrahieren, oder gleich ein richtiges GUI-Rahmenwerk verwenden bevor ich mir so etwas wie `QAction` oder `Gtk.Action` für Tk selber programmiere.

-
- User
- Beiträge: 185
- Registriert: Montag 12. Oktober 2015, 21:24
- Wohnort: Landsberg am Lech
- Kontaktdaten:
@BlackJack:
Danke für Deine Hinweise. Den Vorschlag, den Key-Eventhandler wie die anderen Funktionen zu behandeln und aus dem inneren Kern herauszunehmen, wollte ich testweise umsetzten, bisher allerdings ohne Erfolg. Allerdings sträubt sich in mir auch etwas, diesen Handler mit den anderen Funktionen gleichzusetzen. Das mag aber durchaus daran liegen, dass ich mit Python Null Erfahrungen habe. Vielleicht kannst Du mir dazu einen Denkanstoß geben.
Mein sich schon mehrfach geändertes Skript zu diesem Thread ist nur als Testobjekt gedacht und das einzige Ziel, das ich damit verfolge ist, Erfahrungen mit Python zu sammeln. Im Hinterkopf habe ich natürlich auch immer den Gedanken, wie man dieses Testobjekt eventuell in einer nicht mehrt so ganz trivialen Anwendung verwenden könnte. Eine konkrete Vorstellung dazu habe ich nicht.
MfG, kodela
Danke für Deine Hinweise. Den Vorschlag, den Key-Eventhandler wie die anderen Funktionen zu behandeln und aus dem inneren Kern herauszunehmen, wollte ich testweise umsetzten, bisher allerdings ohne Erfolg. Allerdings sträubt sich in mir auch etwas, diesen Handler mit den anderen Funktionen gleichzusetzen. Das mag aber durchaus daran liegen, dass ich mit Python Null Erfahrungen habe. Vielleicht kannst Du mir dazu einen Denkanstoß geben.
Mein sich schon mehrfach geändertes Skript zu diesem Thread ist nur als Testobjekt gedacht und das einzige Ziel, das ich damit verfolge ist, Erfahrungen mit Python zu sammeln. Im Hinterkopf habe ich natürlich auch immer den Gedanken, wie man dieses Testobjekt eventuell in einer nicht mehrt so ganz trivialen Anwendung verwenden könnte. Eine konkrete Vorstellung dazu habe ich nicht.
MfG, kodela
@kodela: Das geht doch ganz einfach analog zu den anderen Methoden. Wo liegt denn das Problem konkret? Das klingt alles so ein bisschen nach rumprobieren ohne wirklich zu verstanden haben was es mit Klassen, Methoden, und Exemplaren von Klassen auf sich hat.
Weitere Anmerkungen: In Python 2 würde ich immer von `object` erben wenn es keine andere Basisklasse gibt, denn sonst hat man keine „new style”-Klasse und es funktioniert nicht alles was es für Klassen so gibt, wie beispielsweise Properties.
Das `Tk`-Exemplar würde ich nicht `frame` nennen weil das zu sehr verleitet zu glauben es handele sich in Wirklichkeit um ein `Frame`-Exemplar.
Der '\' als Zeilenfortsezung ist nur nötig wenn der Compiler sonst nicht weiss das die ”logische” Zeile noch nicht zuende ist. Solange noch schliessende Klammern ausstehen weiss er das aber. Der '\' hat zudem das Problem das er wirklich als *letztes* Zeichen in der Zeile stehen muss, also auch Leerzeichen dürfen danach keine mehr kommen. Das kann eine nervige, weil nicht offensichtliche Fehlerquelle sein. Deshalb vermeiden viele diese Zeilenfortsezung und setzen zum Beispiel lieber extra Klammern um einen Ausdruck der sich über mehrere Zeilen erstreckt. Also solange nicht sowieso schon Klammern existieren die den '\' überflüssig machen.
Wenn das kein sinnvolles Programm werden soll, also die Aktionsmethoden so bleiben wie sie sind, würde ich das vereinfachen, denn die meisten machen ja fast das selbe. Dafür braucht man ja nicht immer eine neue Methode schreiben, da reicht eine und `partial()`. Da man das dann aber an zwei Stellen braucht, nämlich wenn man die Schaltflächen verbindet und noch einmal wenn man die Tastenereignisse auswertet, braucht man an der Stelle eine Abstraktion wenn man keinen Code doppelt schreiben möchte.
Weitere Anmerkungen: In Python 2 würde ich immer von `object` erben wenn es keine andere Basisklasse gibt, denn sonst hat man keine „new style”-Klasse und es funktioniert nicht alles was es für Klassen so gibt, wie beispielsweise Properties.
Das `Tk`-Exemplar würde ich nicht `frame` nennen weil das zu sehr verleitet zu glauben es handele sich in Wirklichkeit um ein `Frame`-Exemplar.
Der '\' als Zeilenfortsezung ist nur nötig wenn der Compiler sonst nicht weiss das die ”logische” Zeile noch nicht zuende ist. Solange noch schliessende Klammern ausstehen weiss er das aber. Der '\' hat zudem das Problem das er wirklich als *letztes* Zeichen in der Zeile stehen muss, also auch Leerzeichen dürfen danach keine mehr kommen. Das kann eine nervige, weil nicht offensichtliche Fehlerquelle sein. Deshalb vermeiden viele diese Zeilenfortsezung und setzen zum Beispiel lieber extra Klammern um einen Ausdruck der sich über mehrere Zeilen erstreckt. Also solange nicht sowieso schon Klammern existieren die den '\' überflüssig machen.
Wenn das kein sinnvolles Programm werden soll, also die Aktionsmethoden so bleiben wie sie sind, würde ich das vereinfachen, denn die meisten machen ja fast das selbe. Dafür braucht man ja nicht immer eine neue Methode schreiben, da reicht eine und `partial()`. Da man das dann aber an zwei Stellen braucht, nämlich wenn man die Schaltflächen verbindet und noch einmal wenn man die Tastenereignisse auswertet, braucht man an der Stelle eine Abstraktion wenn man keinen Code doppelt schreiben möchte.
-
- User
- Beiträge: 185
- Registriert: Montag 12. Oktober 2015, 21:24
- Wohnort: Landsberg am Lech
- Kontaktdaten:
Das siehst Du völlig richtig. Was ich mache, ist ein Suchen, Bewerten und Ausprobieren (trial and error). Hätte ich Deine Erfahrung mit Python, würde ich mich überhaupt nicht mit solch einem Testobjekt beschäftigen. Und täte ich es doch, bräuchte ich hier keine Fragen zu stellen. Mein Ziel ist es, mich Python anzunähern, zu verstehen, was es mit Klassen, Methoden, und Exemplaren von Klassen auf sich hat. Ein Autodidakt, will er dieses Ziel erreichen, muss dabei wohl zumindest teilweise so vorgehen.BlackJack hat geschrieben:@kodela: . . . Das klingt alles so ein bisschen nach rumprobieren ohne wirklich zu verstanden haben was es mit Klassen, Methoden, und Exemplaren von Klassen auf sich hat. . . .
Es ist vermutlich den meisten Menschen nicht möglich, alles erst in der Theorie zu erlernen und dann das Erlernte problemlos in die Praxis umzusetzen. Man kann zum Beispiel nicht theoretisch das Autofahren erlernen, sich dann in ein Auto setzen und die Fahrprüfung machen. Mir und vielen die hier Fragen stellen, geht es mit Python nicht anders. Manches Mal wird das von Spezialisten übersehen.
Den Keyevent-Handler kann ich nicht so einfach wie die anderen Funktionen behandeln, ich muss ihn in das frame-Objekt einbinden. Damit habe ich dann aber ein Problem.
Deine anderen Hinweise sind teilweise einleuchtend und vorteilhaft, zum Beispiel den Backslash '\' als Zeilenfortsezung. Mit anderen Vorschlägen muss ich mich aber erst noch beschäftigen.
MfG, kodela
@kodela: natürlich muß man selbst ausprobieren um etwas zu lernen. Ich habe aber den Eindruck, dass Du das, was Du ausprobierst gar nicht richtig verstanden hast. Dann hilft Ausprobieren nichts. Um beim Autofahren zu bleiben: wenn man einfach nur irgendwelche Pedale drückt, dann fährt das Auto mal schneller, mal langsamer und man wunder sich, aber die meiste Zeit geht einfach nur der Motor aus und man ärgert sich.
Zurück zum Problem: warum mußt Du den key-Eventhandler anders behandeln? Was ist z.B. der Unterschied zu clear_text?
Zurück zum Problem: warum mußt Du den key-Eventhandler anders behandeln? Was ist z.B. der Unterschied zu clear_text?
-
- User
- Beiträge: 185
- Registriert: Montag 12. Oktober 2015, 21:24
- Wohnort: Landsberg am Lech
- Kontaktdaten:
@Sirius3:
Wenn ich den key-Eventhandler gleich behandle wie clear_text(), wie und wo binde ich jetzt den key-Eventhandler mit frame. Ich weiß es nicht und habe dazu auch nirgendwo etwas konkretes gefunden. Zum Vergleich mit dem, kannst Du mir sagen, welches der Pedale das Bremspedal ist. Spaß beiseite, wie gesagt, ich weiß es nicht und finde trotz mittlerweile stundenlanger Suche nichts, was mir erlauben würde, den key-Eventhandler gleich zu behandeln. Was bleibt mir, alle Möglichkeiten, habe ich erfolglos ausprobiert. Keine der anderen Funktionen erfordert eine Bindung, der Handler aber schon und trotzdem nehmen BlackJack und Du dazu nicht Stellung. Es mag ja eine simple Lösung geben, ich finde sie nicht.
MfG, kodela
Wenn ich den key-Eventhandler gleich behandle wie clear_text(), wie und wo binde ich jetzt den key-Eventhandler mit frame. Ich weiß es nicht und habe dazu auch nirgendwo etwas konkretes gefunden. Zum Vergleich mit dem, kannst Du mir sagen, welches der Pedale das Bremspedal ist. Spaß beiseite, wie gesagt, ich weiß es nicht und finde trotz mittlerweile stundenlanger Suche nichts, was mir erlauben würde, den key-Eventhandler gleich zu behandeln. Was bleibt mir, alle Möglichkeiten, habe ich erfolglos ausprobiert. Keine der anderen Funktionen erfordert eine Bindung, der Handler aber schon und trotzdem nehmen BlackJack und Du dazu nicht Stellung. Es mag ja eine simple Lösung geben, ich finde sie nicht.
MfG, kodela
@kodela: welche Möglichkeiten hast Du denn ausprobiert? Vergleiche mal die Verwendung von clear_text und key:
Was ist unterschiedlich und was ist gleich?
Code: Alles auswählen
self.b_clear = tk.Button(self.panel, text="Löschen",
width=12, height=1, command=self.clear_text)
self.frame.bind('<Key>', key)
@kodela: Du hast die anderen Funktionen zu Methoden gemacht und das geht mit der `key()`-Funktion ganz genau so. Wenn Du das nicht hinbekommst, dann hättest Du das mit den anderen Funktionen auch nicht gekonnt, oder eben nur durch blindes rumprobieren ohne dabei etwas zu lernen. Und dann weiss ich nicht was es bringen soll wenn man Dir jetzt die `key()`-Funktion als Methode zeigt, denn wenn Du das vorher schon nicht mit vergleich Funktion/Methode verstanden hast bei denen die Du schon umgewandelt hast, dann wird hier jetzt höchstens zufällig der Groschen fallen, denn es unterscheidet sich vom vorgehen ja nicht von denen die Du schon zu Methoden gemacht hast. *Wie* hast Du das denn gemacht? Nach welchem systematischen vorgehen? Was hast Du dabei gelernt?
-
- User
- Beiträge: 185
- Registriert: Montag 12. Oktober 2015, 21:24
- Wohnort: Landsberg am Lech
- Kontaktdaten:
Halle @BlackJack:
Wie ich Dir an anderer Stelle bereits mitgeteilt habe, kann ich mich die nächsten Tage nicht mit dem Problem beschäftigen. Ich melde mich aber auf jeden Fall wieder.
MfG, kodela
Wie ich Dir an anderer Stelle bereits mitgeteilt habe, kann ich mich die nächsten Tage nicht mit dem Problem beschäftigen. Ich melde mich aber auf jeden Fall wieder.
MfG, kodela
-
- User
- Beiträge: 185
- Registriert: Montag 12. Oktober 2015, 21:24
- Wohnort: Landsberg am Lech
- Kontaktdaten:
Hallo @BlackJack:
wie ich glaube, habe ich die wichtigsten Änderungsvorschläge von Dir auf die Reihe gebracht. Der Code sieht nun so aus:
Was wäre noch wichtig?
MfG, kodela
wie ich glaube, habe ich die wichtigsten Änderungsvorschläge von Dir auf die Reihe gebracht. Der Code sieht nun so aus:
Code: Alles auswählen
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import Tkinter as tk
import webbrowser
class GUI_Interface(object):
def oeffnen(self):
self.eingabe.delete(0, tk.END)
self.eingabe.insert(0,'Es soll geöffnet werden.')
def speichern(self):
self.eingabe.delete(0, tk.END)
self.eingabe.insert(-1, 'Es soll gespeichert werden.')
def speichern_unter(self):
self.eingabe.delete(0, tk.END)
self.eingabe.insert(-1, 'Es soll unter neuem Namen gespeichert werden.')
def hallo(self):
self.eingabe.delete(0, tk.END)
self.eingabe.insert(-1, 'Hallo!')
def klick(self):
self.eingabe.delete(0, tk.END)
self.eingabe.insert(-1, 'Das war ein Klick!')
def webpage(self):
self.eingabe.delete(0, tk.END)
self.eingabe.insert(-1, 'Python-Forum öffnen')
webbrowser.open("http://www.python-forum.de")
def clear_text(self):
self.eingabe.delete(0,tk.END)
def key(self, event):
# Umschalttasten (Groß/Klein-Ziffernblock) ausmaskieren
_state = event.state & 5
# nur Strg + Zeichentaste
if _state == 4:
if event.keysym.upper() == 'O':
self.oeffnen()
elif event.keysym.upper() == 'S':
self.speichern()
elif event.keysym.upper() == 'Q':
self.root.destroy()
# Strg + Shift + Zeichentaste
elif _state == 5:
if event.keysym.upper() == 'S':
self.speichern_unter()
def __init__(self, tk):
self.root = tk.Tk()
self.root.title('Erstes Fenster')
self.root.geometry('300x130')
menu = tk.Menu(self.root)
filemenu = tk.Menu(menu, tearoff=0)
filemenu.add_command(label='Öffnen . . .',
accelerator='Strg+O', command=self.oeffnen)
filemenu.add_command(label='Speichern . . .',
accelerator='Strg+S', command=self.speichern)
filemenu.add_command(label='Speichern unter . . .\t\t\t',
accelerator='Strg+Shift+S', command=self.speichern_unter)
filemenu.add_separator()
filemenu.add_command(label='Beenden',
accelerator='Strg+Q', command=self.root.quit)
menu.add_cascade(label='Datei', menu=filemenu)
editmenu = tk.Menu(menu, tearoff=0)
editmenu.add_command(label='Forum öffnen', command=self.webpage)
editmenu.add_command(label='Pause', command=self.hallo)
editmenu.add_command(label='Einfügen', command=self.klick)
menu.add_cascade(label='Bearbeiten', menu=editmenu)
helpmenu = tk.Menu(menu, tearoff=0)
helpmenu.add_command(label='Über', command=self.hallo)
menu.add_cascade(label='Hilfe', menu=helpmenu)
self.root.config(menu=menu)
self.panel = tk.Frame(self.root)
self.eingabe = tk.Entry(self.panel)
self.eingabe.insert(0,'Hallo Welt!')
self.eingabe.pack(fill=tk.X, padx=15, pady=20)
self.b_clear = tk.Button(self.panel, text="Löschen",
width=12, height=1, command=self.clear_text)
self.b_clear.pack(side="left", padx=20, pady=10)
self.b_quit = tk.Button(self.panel, text="Beenden",
width=12, height=1, command=self.root.quit)
self.b_quit.pack(side="right", padx=20, pady=10)
self.panel.pack(fill=tk.X)
self.root.bind('<Key>', self.key)
def main():
app = GUI_Interface(tk)
app.root.mainloop()
if __name__ == '__main__':
main()
MfG, kodela