GUI – 38 Eingabefelder und 38 Beschriftungen
- Strawk
- User
- Beiträge: 233
- Registriert: Mittwoch 15. Februar 2017, 11:42
- Wohnort: Aachen
- Kontaktdaten:
Hallo!
Bin jetzt einen Schritt weiter und die Widgets sind im Frame.
Aktuelles Problem: Ich habe die Datenbankabfrage in ein externes Skript und in eine dortige Funktion ausgelagert. Wie erreiche ich jetzt, dass das SQL-result im aufrufenden (Haupt-)Skript im Textfenster ausgegeben werden kann?
Bisher funktioniert das in beiden Richtungen nicht. Will heißen: Entweder kennt das Unter-Skript das Textfenster nicht, oder das Haupt-Skript kennt das SQL-result nicht. Gibt es einen Befehl, ein Objekt wie "result" global verfügbar zu machen? Oder wie anders realisiere ich das?
Grüße
Strawk
Bin jetzt einen Schritt weiter und die Widgets sind im Frame.
Aktuelles Problem: Ich habe die Datenbankabfrage in ein externes Skript und in eine dortige Funktion ausgelagert. Wie erreiche ich jetzt, dass das SQL-result im aufrufenden (Haupt-)Skript im Textfenster ausgegeben werden kann?
Bisher funktioniert das in beiden Richtungen nicht. Will heißen: Entweder kennt das Unter-Skript das Textfenster nicht, oder das Haupt-Skript kennt das SQL-result nicht. Gibt es einen Befehl, ein Objekt wie "result" global verfügbar zu machen? Oder wie anders realisiere ich das?
Grüße
Strawk
Ich programmiere erfolglos, also bin ich nicht.
- Strawk
- User
- Beiträge: 233
- Registriert: Mittwoch 15. Februar 2017, 11:42
- Wohnort: Aachen
- Kontaktdaten:
Hallo __deets__!
Nein, zur skriptübergreifenden Übergabe steht im Einstiegsbuch nichts. Wäre es ein Ansatz, das SQL-Abfrageergebnis als Instanz einer Klasse zu gestalten? Wie sähe dann die Klassendefinition grob aus?
Grüße
Strawk
Nein, zur skriptübergreifenden Übergabe steht im Einstiegsbuch nichts. Wäre es ein Ansatz, das SQL-Abfrageergebnis als Instanz einer Klasse zu gestalten? Wie sähe dann die Klassendefinition grob aus?
Grüße
Strawk
Ich programmiere erfolglos, also bin ich nicht.
Natuerlich steht dazu etwas darin. Es behandelt Module, also die Aufteilung eines Programms in mehrere Teile. Und es behandelt Funktionen mit Parametern und Rueckgabewerten. Das findet sich im Inhaltsverzeichnis:
https://www.rheinwerk-verlag.de/einstie ... n_4374/toc
Deutlich vor der von dir angegebenen Seitennummer irgendwo bei 370.
Und die Ergebnisse einer Abfrage sind ja schon ein Objekt - naemlich ein Cursor. An sich kann man den auch einfach zurueckgeben. Allerdings kann man sich da Aerger einhandeln, weil dessen Gueltigkeit an der Verbindung und anderen Einfluessen haengt. Aber ein simples "return cursor.fetchall()" reicht, und du hast dein Objekt - eine Liste von Tupeln.
https://www.rheinwerk-verlag.de/einstie ... n_4374/toc
Deutlich vor der von dir angegebenen Seitennummer irgendwo bei 370.
Und die Ergebnisse einer Abfrage sind ja schon ein Objekt - naemlich ein Cursor. An sich kann man den auch einfach zurueckgeben. Allerdings kann man sich da Aerger einhandeln, weil dessen Gueltigkeit an der Verbindung und anderen Einfluessen haengt. Aber ein simples "return cursor.fetchall()" reicht, und du hast dein Objekt - eine Liste von Tupeln.
- Strawk
- User
- Beiträge: 233
- Registriert: Mittwoch 15. Februar 2017, 11:42
- Wohnort: Aachen
- Kontaktdaten:
Hallo __deets__!
Das funktioniert schon anhand einfacher Beispiele nicht.
ergibt
Strawk
Das funktioniert schon anhand einfacher Beispiele nicht.
Code: Alles auswählen
def testFunktion():
a = 42
return a
Code: Alles auswählen
import sys
sys.path.append('C:/Users/Karl Kraft/Documents/Programmierung_ausser_PHP/Python/Anaconda_Navigator/Liverecord_Python')
import aufgerufenes_skript_01
aufgerufenes_skript_01.testFunktion()
print a
GrüßeNameError: name 'a' is not defined
Strawk
Ich programmiere erfolglos, also bin ich nicht.
Ja, weil a nur im Namensraum der Funktion bekannt ist. Das schwirrt nicht einfach so im Raum. Schon gar nicht modulübergreifend. Aus solchen Gründen solltest du dich mit den Grundlagen beschäftigen, bevor du weiter an GUI-Programmierung herumdoktorst. Das dauert nun mal ein paar Monate bis man es drauf hat. Das lernt man nicht an 3 Abenden. Mit anderen Worten: Du hast gerade Plus und Minus gelernt und willst direkt zur Analysis übergehen. Das funktioniert eben nicht.
Zuletzt geändert von snafu am Sonntag 10. Dezember 2017, 17:22, insgesamt 1-mal geändert.
@Strawk: erstens ist das kein Skript das da aufgerufen wird, sondern Du importierst ein Modul, zweitens lergt man das Modul in ein Verzeichnis, das schon im Modulpfad ist (z.B. das aktuelle) drittens gibt man dem Modul einen sinnvollen Namen. Und jetzt lies nochmal nach, wie das mit den Funktionen funktioniert.
- Strawk
- User
- Beiträge: 233
- Registriert: Mittwoch 15. Februar 2017, 11:42
- Wohnort: Aachen
- Kontaktdaten:
Hallo!
Och, Leute, lasst euch doch nicht alles aus der Nase ziehen. Ja, ich gebe dir recht, dass das mindestens Monate, wenn nicht Jahre dauert. Aber ist denn eure Rolle im Forum, immer einfach nur zu sagen: Finde es selbst raus? Also, wie mache ich die Variable/das Objekt außerhalb nun bekannt?
Grüße
Strawk
Och, Leute, lasst euch doch nicht alles aus der Nase ziehen. Ja, ich gebe dir recht, dass das mindestens Monate, wenn nicht Jahre dauert. Aber ist denn eure Rolle im Forum, immer einfach nur zu sagen: Finde es selbst raus? Also, wie mache ich die Variable/das Objekt außerhalb nun bekannt?
Grüße
Strawk
Ich programmiere erfolglos, also bin ich nicht.
Du musst einen rückgabewert schon an einen Namen binden. Der erscheint nicht magisch in dem Namensraum um die aufrufstelle herum.
Das steht auch so ganz bestimmt NICHT in deinem Buch. Du wirst nicht darum herum kommen, das nochmal anzuschauen.
Code: Alles auswählen
wert = funktion_die_was_tut()
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
Bei der GUI-Programmierung mit Python ist es _essentiell_ wichtig, dass man die Objektorientierung von Python verstanden hat - sonst wird das nix. Alle GUI-Frameworks, nicht nur Tkinter, nutzen das sehr umfassend. Mit Python anfangen und dann direkt eine (größere) GUI programmieren wollen geht nun mal in der Regel schief...
In der Tat sehen die meisten das hier als "Hilfe zur Selbsthilfe", zumindest bei den gängigen / nicht-schwierigen Problemen wie diesem hier.
Gruß, noisefloor
Unter Python nutzt man _keine_ globalen Namensraum, über den Werte von Variablen abgerufen werden können. Entweder nutzt du Instanzen von Objekten, deren Attribute Werte enthalten (können) oder du bindest einen Wert an die Rückgabe einer Funktion wie gezeigt.Gibt es einen Befehl, ein Objekt wie "result" global verfügbar zu machen?
Bei der GUI-Programmierung mit Python ist es _essentiell_ wichtig, dass man die Objektorientierung von Python verstanden hat - sonst wird das nix. Alle GUI-Frameworks, nicht nur Tkinter, nutzen das sehr umfassend. Mit Python anfangen und dann direkt eine (größere) GUI programmieren wollen geht nun mal in der Regel schief...
Aber ist denn eure Rolle im Forum, immer einfach nur zu sagen: Finde es selbst raus?
In der Tat sehen die meisten das hier als "Hilfe zur Selbsthilfe", zumindest bei den gängigen / nicht-schwierigen Problemen wie diesem hier.
Gruß, noisefloor
- Strawk
- User
- Beiträge: 233
- Registriert: Mittwoch 15. Februar 2017, 11:42
- Wohnort: Aachen
- Kontaktdaten:
Hallo!
Also, was die Funktions-Syntax betraf, da habe ich mich dumm angestellt; das gebe ich zu / räume ich ein.
Positiv: Ich komme jedesmal ein Stück weiter und habe schon einige Probleme (nicht zuletzt mit eurer Hilfe) lösen können. Außerdem meine ich, wenn die Ausgabe einmal gelungen ist, ist das auch der Durchbruch. Man darf dabei nicht vergessen, dass das ganze Projekt ja schon steht und fehlerfrei läuft, halt nur in PHP.
Und so komme ich zu meiner aktuellen Frage. Momentan sieht die Ausgabe so aus:
Sie soll aber in ein großes Entry-Feld hinein, mit Scrollbalken. Und auch tabellarisch. Wie kann ich das realisieren? Wie lautet der entsprechende Befehl und: kann ich im Entry-Feld mit String-Literalen arbeiten?
Viele Grüße
Strawk
Also, was die Funktions-Syntax betraf, da habe ich mich dumm angestellt; das gebe ich zu / räume ich ein.
Positiv: Ich komme jedesmal ein Stück weiter und habe schon einige Probleme (nicht zuletzt mit eurer Hilfe) lösen können. Außerdem meine ich, wenn die Ausgabe einmal gelungen ist, ist das auch der Durchbruch. Man darf dabei nicht vergessen, dass das ganze Projekt ja schon steht und fehlerfrei läuft, halt nur in PHP.
Und so komme ich zu meiner aktuellen Frage. Momentan sieht die Ausgabe so aus:
Code: Alles auswählen
# Daten ausgeben
for data in abfrageergebnis:
print(unicode(data[0]) + ", " + unicode(data[1]) + ", " +
unicode(data[2]) + ", " + unicode(data[3]) + ", " +
unicode(data[4]) + ", " + unicode(data[5]) + ", " +
unicode(data[6]) + ", " + unicode(data[7]) + ", " +
unicode(data[8]) + ", " + unicode(data[9]) + ", " +
unicode(data[10]) + ", " + unicode(data[11]) + ", " +
unicode(data[12]) + ", " + unicode(data[13]) + ", " +
unicode(data[14]) + ", " + unicode(data[15]) + ", " +
unicode(data[16]) + ", " + unicode(data[17]) + ", " +
unicode(data[18]) + ", " + unicode(data[19]) + ", " +
unicode(data[20]) + ", " + unicode(data[21]) + ", " +
unicode(data[22]) + ", " + unicode(data[23]) + ", " +
unicode(data[24]) + ", " + unicode(data[25]) + ", " +
unicode(data[26]) + ", " + unicode(data[27]) + ", " +
unicode(data[28]) + ", " + unicode(data[29]) + ", " +
unicode(data[30]) + ", " + unicode(data[31]) + ", " +
unicode(data[32]) + ", " + unicode(data[33]) + ", " +
unicode(data[34]) + ", " + unicode(data[35]) + ", " +
unicode(data[36]) + ", " + unicode(data[37]))
Viele Grüße
Strawk
Ich programmiere erfolglos, also bin ich nicht.
@Strawk: das, was unter PHP als akzeptabler Programmierstil durchgeht, kann man halt mit Python dreimal eleganter lösen. Dir fehlen noch viele Grundlagen.
Tabellen macht man per `.grid`. Aber ehrlich, 38 Spalten liest doch niemand.
Code: Alles auswählen
for data in abfrageergebnis:
print(", ".join(["{}"]*38).format(*data))
- Strawk
- User
- Beiträge: 233
- Registriert: Mittwoch 15. Februar 2017, 11:42
- Wohnort: Aachen
- Kontaktdaten:
Hallo Sirius3!
Doch. In der Ergebnisanzeige müssen keine 38 Spalten nebeneinander stehen. Man kann sie auch teilweise untereinander anordnen und dann mit Blöcken pro Datensatz/Tupel arbeiten.
Wichtiger jetzt aber: Wie gelangt das Ergebnis ins Textfeld. (Nicht Entry! Hab mich vertan.)
Die .insert-Methode verlangt drei Argumente, das zweite davon ist der auszugebende Text. Wenn man es googelt, findet man:
bzw.
Funktioniert aber (noch) nicht.
Grüße
Strawk
Doch. In der Ergebnisanzeige müssen keine 38 Spalten nebeneinander stehen. Man kann sie auch teilweise untereinander anordnen und dann mit Blöcken pro Datensatz/Tupel arbeiten.
Wichtiger jetzt aber: Wie gelangt das Ergebnis ins Textfeld. (Nicht Entry! Hab mich vertan.)
Die .insert-Methode verlangt drei Argumente, das zweite davon ist der auszugebende Text. Wenn man es googelt, findet man:
Code: Alles auswählen
.insert(index, text, tags=None)
Code: Alles auswählen
.insert(END, text)
Grüße
Strawk
Ich programmiere erfolglos, also bin ich nicht.
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
@Strawk: Zwischenfrage - warum willst du das eigentlich von web-basiert und PHP auf (Desktop-) GUI-basiert und Python umstellen?
Gruß, noisefloor
@Strawk: Zwischenfrage - warum willst du das eigentlich von web-basiert und PHP auf (Desktop-) GUI-basiert und Python umstellen?
Gruß, noisefloor
- Strawk
- User
- Beiträge: 233
- Registriert: Mittwoch 15. Februar 2017, 11:42
- Wohnort: Aachen
- Kontaktdaten:
Hallo noisefloor!
Das ist eine längere Geschichte. Hier die Kurzversion.
Arbeite seit 2011 mit PHP. Mein bisher größtes Projekt: "Liverecord". Eine Datenbank, die Menschen und ihre Lebensdaten speichern kann. Empfehlung meines Ingenieur-Cousins im Februar 2017: Python erlernen, weil man damit am meisten machen kann. Erste Übung: Das Projekt in Python übersetzen.
So sieht das im Moment übrigens aus:
Erbitte Hilfe zum Gliedern innerhalb eines Text-Widgets.
Grüße, Strawk
Das ist eine längere Geschichte. Hier die Kurzversion.
Arbeite seit 2011 mit PHP. Mein bisher größtes Projekt: "Liverecord". Eine Datenbank, die Menschen und ihre Lebensdaten speichern kann. Empfehlung meines Ingenieur-Cousins im Februar 2017: Python erlernen, weil man damit am meisten machen kann. Erste Übung: Das Projekt in Python übersetzen.
So sieht das im Moment übrigens aus:
Erbitte Hilfe zum Gliedern innerhalb eines Text-Widgets.
Grüße, Strawk
Ich programmiere erfolglos, also bin ich nicht.
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
aha. Gut ist zum Lernen immer, wann man ein Ziel hat
Aber:
Außerdem bedeutet GUI-Programmierung relativ viel Code, der "nur" für die Erstellung der GUI notwendig ist. Die reine Programmlogik kann vergleichsweise gering sein - das ist aber das, was du lernen möchtest / solltest.
GUI-Programmierung erfordet grundlegende Kenntnis der Objektorientierung, sonst kommt kein brauchbarer Code raus. Bei 38 Feldern ist eine gewisse Aufteilung, GUIs auf mehrere Module aufteilen ist aber für Einsteiger mehr als sportlich.
GUI + Datenbank-Anbindung ist IMHO auch kein Thema für Einsteiger.
Was du machen könntest:
* lass' dein Projekt ruhen und lerne vernünftig die Grundlagen von Python
* reduziert dein Übungsprojekt auf 5 Felder oder so, dass macht die Sache einfacher und übersichtlicher
* vergiß' Tkinter und setze es mit Web-basierte Applikation mit Python um. Ist auch einfacher als Tkinter & Co.
* vergiß' Tkinter und wechsel auf Qt, weil das eine Anbindung an SQL-Datenbanken ootb mitbringt
Gruß, noisefloor
aha. Gut ist zum Lernen immer, wann man ein Ziel hat
Aber:
IMHO ist das keine gute Übung, weil 3-5 Nummern zu groß. Das die Grundlagen fehlen, wurde ja hier schon öfters erwähnt.Erste Übung: Das Projekt in Python übersetzen.
Außerdem bedeutet GUI-Programmierung relativ viel Code, der "nur" für die Erstellung der GUI notwendig ist. Die reine Programmlogik kann vergleichsweise gering sein - das ist aber das, was du lernen möchtest / solltest.
GUI-Programmierung erfordet grundlegende Kenntnis der Objektorientierung, sonst kommt kein brauchbarer Code raus. Bei 38 Feldern ist eine gewisse Aufteilung, GUIs auf mehrere Module aufteilen ist aber für Einsteiger mehr als sportlich.
GUI + Datenbank-Anbindung ist IMHO auch kein Thema für Einsteiger.
Was du machen könntest:
* lass' dein Projekt ruhen und lerne vernünftig die Grundlagen von Python
* reduziert dein Übungsprojekt auf 5 Felder oder so, dass macht die Sache einfacher und übersichtlicher
* vergiß' Tkinter und setze es mit Web-basierte Applikation mit Python um. Ist auch einfacher als Tkinter & Co.
* vergiß' Tkinter und wechsel auf Qt, weil das eine Anbindung an SQL-Datenbanken ootb mitbringt
Du musst den Text formatiert, also z.B. mit Zeilenumbrüchen, übergeben.Erbitte Hilfe zum Gliedern innerhalb eines Text-Widgets.
Gruß, noisefloor
Das geht noch einfacher:Sirius3 hat geschrieben:@Strawk: das, was unter PHP als akzeptabler Programmierstil durchgeht, kann man halt mit Python dreimal eleganter lösen. Dir fehlen noch viele Grundlagen.
Code: Alles auswählen
for data in abfrageergebnis: print(", ".join(["{}"]*38).format(*data))
Code: Alles auswählen
print(*data, sep=', ')
Code: Alles auswählen
print u', '.join(map(unicode, data))
Hi Strawk
Hier ein Ausgabeversuch mittels Tk-Textwidget:
Gruss wuf
Hier ein Ausgabeversuch mittels Tk-Textwidget:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from functools import partial
try:
# Tkinter for Python 2.xx
import Tkinter as tk
import tkFont as fnt
except ImportError:
# Tkinter for Python 3.xx
import tkinter as tk
import tkinter.font as fnt
APP_TITLE = "Datenausgabe (19 Datenpaare)"
APP_XPOS = 100
APP_YPOS = 100
APP_WIDTH = 350
APP_HEIGHT = 200
class Application(tk.Frame):
def __init__(self, parent, abfrageergebnis):
self.parent = parent
self.parent.protocol("WM_DELETE_WINDOW", self.close)
tk.Frame.__init__(self, parent)
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
xscrollbar = tk.Scrollbar(self, orient='horizontal')
xscrollbar.grid(row=1, column=0, sticky='ew')
yscrollbar = tk.Scrollbar(self)
yscrollbar.grid(row=0, column=1, sticky='ns')
text = tk.Text(self, wrap='none', bd=0, xscrollcommand=xscrollbar.set,
yscrollcommand=yscrollbar.set, fg='steelblue3')
text.grid(row=0, column=0, sticky='nsew')
xscrollbar.config(command=text.xview)
yscrollbar.config(command=text.yview)
for data in abfrageergebnis:
# Data Tuple Zeile im Textwidget ausgeben
# Platzhalter 20 Zeichen
text.insert(1.0, " {:20} {:20}\n".format(*data))
def close(self):
print("Application-Shutdown")
self.parent.destroy()
def main():
app_win = tk.Tk()
app_win.title(APP_TITLE)
app_win.geometry("+{}+{}".format(APP_XPOS, APP_YPOS))
app_win.geometry("{}x{}".format(APP_WIDTH, APP_HEIGHT))
# Simulationsdaten erstellen (19 Datenpaare)
abfrageergebnis = list()
index = 1
for pair_index in range(19):
abfrageergebnis.append(
("Data-{}".format(index), "Data-{}".format(index+1)))
index += 2
# Simulationsdatenliste kehren damit das erste Datentuple als letzte
# Zeile dem Textwidget übergeben wird und somit zuoberst steht.
abfrageergebnis.reverse()
app = Application(app_win, abfrageergebnis)
app.pack(fill='both', expand=True, padx=6, pady=6)
app_win.mainloop()
if __name__ == '__main__':
main()
Take it easy Mates!
- Strawk
- User
- Beiträge: 233
- Registriert: Mittwoch 15. Februar 2017, 11:42
- Wohnort: Aachen
- Kontaktdaten:
Hallo!
noisefloor, das sind sicherlich kluge Gedanken und Ideen, die du da kundtust. Eine Weile möchte ich mein Glück aber noch am Projekt versuchen.
Aktuell geht es darum, die Entry-Einträge, die ein User in der Maske gemacht hat, per Schleife auszulesen.
Die Namen der Entry-Widgets lauten immer "e_*".
* = feldname. Folgenden Code habe ich dazu erstellt:
Problem: Was jetzt als String vorliegt, soll als Wert einer weiteren Liste hinzugefügt werden, sodass eine Liste der in die Entrys gemachten Eingaben entsteht. Erbitte Hilfe.
Grüße
Strawk
noisefloor, das sind sicherlich kluge Gedanken und Ideen, die du da kundtust. Eine Weile möchte ich mein Glück aber noch am Projekt versuchen.
Aktuell geht es darum, die Entry-Einträge, die ein User in der Maske gemacht hat, per Schleife auszulesen.
Die Namen der Entry-Widgets lauten immer "e_*".
* = feldname. Folgenden Code habe ich dazu erstellt:
Code: Alles auswählen
def buttonNachKriterienAnzeigenClick():
felder = ["nummer", "codierung",
"name_oder_firmenname", "geburtsname", "vorname_bezeichnung",
"strasse_hausnummer", "plz", "ort",
"ortsteil", "bundesland_provinz_kanton", "land_nation",
"fahrzeugfabrikat", "fahrzeugtyp", "kfz_kennzeichen_historie",
"landesvorwahl", "festnetzvorwahl", "festnetznummer",
"aktiv", "mobile_vorwahl", "mobiler_anschluss",
"e_mail_1", "e_mail_2", "url",
"geschlecht", "anzahl_kinder", "verstorben_am_um",
"geburtstag", "anzahl_ereignisse", "memos",
"fax", "titel", "beruf",
"ausbildung", "taetigkeit", "taetig_in_firma",
"hobbys", "herkunftsland", "bekanntschaft_seit"]
kriterien = []
for feld in felder:
kriterien.append("e_" + feld + ".get()")
print(kriterien)
Grüße
Strawk
Ich programmiere erfolglos, also bin ich nicht.
@Strawk: falscher Weg. Ich habe in meinem Beispiel vom 3. Dezember alle Entries in eine Liste gepackt, die parallel zur LABELS-Liste gelesen werden muß. Alternativ kann man auch ein Wörterbuch verwenden. Für einen Datensatz bietet sich auch ein Namedtuple an.