GUI – 38 Eingabefelder und 38 Beschriftungen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

aha. Gut ist zum Lernen immer, wann man ein Ziel hat :-)

Aber:
Erste Übung: Das Projekt in Python übersetzen.
IMHO ist das keine gute Übung, weil 3-5 Nummern zu groß. Das die Grundlagen fehlen, wurde ja hier schon öfters erwähnt.
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
Erbitte Hilfe zum Gliedern innerhalb eines Text-Widgets.
Du musst den Text formatiert, also z.B. mit Zeilenumbrüchen, übergeben.

Gruß, noisefloor
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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))
Das geht noch einfacher:

Code: Alles auswählen

print(*data, sep=', ')
Oder ohne print()-Funktion unter Python 2.7:

Code: Alles auswählen

print u', '.join(map(unicode, data))
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Strawk

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()      
Gruss wuf :wink:
Take it easy Mates!
Benutzeravatar
Strawk
User
Beiträge: 227
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:

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)
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
:)
Ich programmiere erfolglos, also bin ich nicht.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@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.
Benutzeravatar
Strawk
User
Beiträge: 227
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hallo Sirius3!

Dass deine Lösung die x-mal bessere und professionellere ist, kann ich mir schon lebhaft vorstellen. Aber schau bitte dennoch, was ich erreichen konnte:
['33', 'pers', 'Datec', '', '', 'Severin', '42089', '', 'Neukirch', '', '', '', '', '', '', '', '12345', '', '', '', '', '', '', '', '', '', '', '', 'bekannt', '', 'Doktor', '', '', '', 'Volkswagen', '', '', '']
Das ist die Liste "Werte" und die kann ich jetzt weiterverarbeiten.

Grüße
Strawk
:wink:
Ich programmiere erfolglos, also bin ich nicht.
Benutzeravatar
Strawk
User
Beiträge: 227
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hallo!

Diesen SQL-Abfrage-String hat mein Programm automatisch anhand der Eingaben in die Maske generiert:
select * from dauner where e_geburtstag LIKE '06.10.1971' AND e_nummer LIKE '44' AND e_codierung LIKE 'gym' AND e_taetigkeit LIKE 'Vorarbeiter' AND e_vorname_bezeichnung LIKE 'Martin' AND e_taetig_in_firma LIKE 'Volkswagen' AND e_name_oder_firmenname LIKE 'Datec' AND
Ihn möchte ich nun dahingehend bearbeiten, dass die letzten vier Stellen (das " AND") abgeschnitten werden. Mit dem Befehl

Code: Alles auswählen

abfrage = abfrage[:-4]
erhalte ich jedoch nicht das gewünschte Ergebnis, sondern
e_geburtse_taetigkeit LIKE 'Vorarbeite_vorname_bezeichnung LIKE 'Martin' e_taetig_in_firma LIKE 'Volkswagen' e_name_oder_firmenna
also einen verstümmelten String. Was mache ich falsch?

Grüße
Strawk
:D
Ich programmiere erfolglos, also bin ich nicht.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@Strawk: Du machst irgendetwas anders, als das, was Du glaubst zu tun. Zeig doch Deinen kompletten Code.

Entscheidender Fehler ist, dass das "AND" überhaupt im String steht. Zweiter Fehler ist, dass das automatisch generiert wird, dritter Fehler ist, dass Du keine Platzhalter verwendest, vierter Fehler ist, dass Du `select *` benutzt, fünfter Fehler ist, dass alle Spaltennamen ein `e_` enthalten.

LIKE ohne Jokerzeichen ist sinnlos.
Benutzeravatar
Strawk
User
Beiträge: 227
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hallo Sirius3!

Ziel ist, das Projekt "Liverecord" in Python umzuschreiben und die Ausgangs-Struktur von "Liverecord" ist nun mal so. Zu den von dir angemerkten Fehlern:
  1. "AND" muss meiner Meinung nach im String stehen, um alle eingetragenen Werte abzudecken.
  2. Der SQL-String muss automatische generiert werden, sonst wäre der User am Frontend gezwungen, sich über SQL Gedanken zu machen.
  3. Platzhalter habe ich eingefügt.
  4. "SELECT" ist meiner Ansicht nach zwingend. Welches SQL-Kommando sollte wohl sonst die Daten abfragen?
  5. Das "_e" möchte ich über "replace" entfernen.
Daher zur Ausgangsfrage: Wieso gelingt es nicht, vom String die letzen 4 Zeichen zu löschen?

Grüße
Strawk 8)
Ich programmiere erfolglos, also bin ich nicht.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

1) AND muss *ZWISCHEN* den Klauseln stehen. Nicht dahinter, und dann muss man das auch nicht mehr abschneiden.
3) Ich sehe keine Platzhalter, sondern konkrete Werte. Insofern ist das aller Wahrscheinlichkeit immer noch ein Fehler, weil du damit zB Fehleingaben zulaesst, die deine Datenbank zerstoeren koennen.
4) Natuerlich ist SELECT notwendig, das hat Sirius3 auch nicht gemeint. Sondern den "*". Man schreibt solchen Code nicht, weil man sich damit Probleme einhandelt, wenn man mal an der Datenbankstruktur rumschraubt. Darum listet man die Felder die man haben will explizit auf, und wird dann nicht von mehr, weniger oder anderen Reihenfolgen ueberrascht.
5) Etwas ueber replace zu entfernen wenn man die Kontrolle darueber hat, wie man es zusammenbaut ist eine fragwuerdige Idee. Und wenn ich jetzt bei "e_mobile" gearbeitet habe, zerbrichst du mir dann meine Abfrage?

Last but not least: deine Ausgangsfrage ist so nicht zu beantworten, da der Python-Interpreter recht gut darin ist, von einem String 4 Zeichen abzuschaelen. Das funktioniert Milliardenfach jede Sekunde auf der Welt. Da es bei dir nicht geht, musst du drumrum irgendetwas anders machen, als sich das ohne weitere Informationen erschliessen laesst.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Strawk

Hast du das folgende einmal ausprobiert?:

Code: Alles auswählen

data = "select * from dauner where e_geburtstag LIKE '06.10.1971' AND e_nummer LIKE '44' AND e_codierung LIKE 'gym' AND e_taetigkeit LIKE 'Vorarbeiter' AND e_vorname_bezeichnung LIKE 'Martin' AND e_taetig_in_firma LIKE 'Volkswagen' AND e_name_oder_firmenname LIKE 'Datec' AND"    
mod_data = data.replace(" AND", "")
print(mod_data)
eval(mod_data)
Gruss wuf
Take it easy Mates!
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

wuf hat geschrieben: Hast du das folgende einmal ausprobiert?:

Code: Alles auswählen

data = "select * from dauner where e_geburtstag LIKE '06.10.1971' AND e_nummer LIKE '44' AND e_codierung LIKE 'gym' AND e_taetigkeit LIKE 'Vorarbeiter' AND e_vorname_bezeichnung LIKE 'Martin' AND e_taetig_in_firma LIKE 'Volkswagen' AND e_name_oder_firmenname LIKE 'Datec' AND"    
mod_data = data.replace(" AND", "")
print(mod_data)
eval(mod_data)
Gruss wuf
Was soll es denn bringen, alle ANDs aus einem SQL-statement zu entfernen? Dann ist das nicht mehr syntaktisch gueltig.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

__deets__ hat geschrieben:Was soll es denn bringen, alle ANDs aus einem SQL-statement zu entfernen? Dann ist das nicht mehr syntaktisch gueltig.
OK. Mit SQL bin ich leider nicht so bewandert. Dachte er wolle alle 'AND' entfernen. Wenn es aber nur das letze 'AND' zu entfernen gibt sollte das folgende doch gehen?:

Code: Alles auswählen

data = "select * from dauner where e_geburtstag LIKE '06.10.1971' AND e_nummer LIKE '44' AND e_codierung LIKE 'gym' AND e_taetigkeit LIKE 'Vorarbeiter' AND e_vorname_bezeichnung LIKE 'Martin' AND e_taetig_in_firma LIKE 'Volkswagen' AND e_name_oder_firmenname LIKE 'Datec' AND"    
mod_data = data[:-4]
print(mod_data)
eval(mod_data)
Gruss wuf :wink:
Take it easy Mates!
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

@wuf: das ist aber nur ein Würg-Around des eigentlichen Problems... Man sollte den String direkt so bauen, dass man an seinem frisch gebauten String nicht direkt beschneiden muss. Was eigentlich kein Problem sein sollte.

@Strawk: zeig mal bitte den Code, wo du den (SQL-) String baust.

Gruß, noisefloor
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@wuf: was soll denn das bringen, ein SQL-Select mit `eval` auszuführen, wo nebenbei `eval` generell nicht zu benutzen ist.
Benutzeravatar
Strawk
User
Beiträge: 227
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hello again!

Der SQL-String wird jetzt korrekt erstellt. Ich bin schon beim nächsten Problem:

Ein SQL-Befehl
INSERT INTO dauner (taetig_in_firma, ort_stadt, name_oder_firmenname) VALUES ('Test', 'Test', 'Test')
wird korrekt ausgegeben. Aber die Methode

Code: Alles auswählen

cursor.execute(sql_abfrage_string)
ist ohne Wirkung; der Tabelle wird kein Datensatz/Tupel hinzugefügt. Allerdings erscheint auch keinerlei Fehlermeldung. Erbitte Hilfe.

Grüße
Strawk
:)
Ich programmiere erfolglos, also bin ich nicht.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

COMMIT ist dein Freund. Bzw connection.commit()
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@Strawk: wenn Dein execute beim SELECT so aussieht, wie beim INSERT, wird der SQL-String nicht korrekt erstellt. Du willst anscheinend keine Hilfe, weil Du Deinen Code so verheimlichst und auf Anmerkungen nicht reagierst.
Benutzeravatar
Strawk
User
Beiträge: 227
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hallo!

Kann ich euch den Gesamtcode als ZIP-Datei hochladen?

Grüße
Strawk
:D
Ich programmiere erfolglos, also bin ich nicht.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du koenntest github bemuehen. Oder pastebin. ZIP ist aetzend, weil man mehrere Schritte gehen muss, um es zu betrachten, und das dann nicht mehr im Browser.
Antworten