Vergleichs Programm

Fragen zu Tkinter.
Antworten
Eisi
User
Beiträge: 62
Registriert: Sonntag 24. November 2013, 21:59

Hallo zusammen,

ich habe mich jetzt schon einige Tage in Phyton versucht und bin nun dabei mir Tkinter anzuschauen. Ich würde da gerne ein Programm schreiben, welches 2 eingaben miteinander vergleicht. Wenn ich in das erste Feld eine Eingabe gemacht habe und diese mit Enter bestätige soll er automatisch zur 2. eingabe gehen. Nach der Eingabe in das 2. Feld soll er wieder zur ersten gehen und die darin enthaltene eingabe markieren sodass man sofort die nächste machen kann. Und natürlich soll er mir ausgeben ob die Eingaben identisch sind (Richtig) und ob sie Falsch sind.

Ich hab da schon was angefangen und mehrere wege versucht aber ich bekomme es leider nicht hin.

Das ist mein aktueller Code und ich benutzte Python 3.3.2

ich hoffe ihr könnt mir denkanstöße geben oder Helfen

Code: Alles auswählen

from tkinter import *


def test():
    if entry1 == entry2:
        Label(tk, text='              Richtig              ', font='Arial, 120', bg='green', fg='black').pack()

    else:
        Label(tk, text='              Falsch               ', font='Arial, 120', bg='red', fg='black').pack()

tk = Tk()



entry1 = Entry(tk, font='Arial, 120').pack()
entry2 = Entry(tk, font='Arial, 120').pack()

Label(tk, text=test(), font='Arial, 120').pack()

tk.mainloop()
Vielen Dank Christoph
BlackJack

@Eisi: Dir fehlen recht eindeutig absolute Grundlagen. Als erstes solltest Du mal Python-Grundlagen bis einschliesslich objektorientierter Programmierung lernen, und dann erst über GUI-Programmierung nachdenken.

An `entry1` und `entry2` wird der Rückgabewert der `pack()`-Methode gebunden. Der ist immer `None` und damit ist der Vergleich in `test()` immer wahr. Wenn an die Namen die `Entry`-Objekte gebunden wären, würde der Vergleich immer noch keinen Sinn machen weil dann natürlich immer „falsch” bei dem Vergleich heraus käme. Es handelt sich ja ganz offensichtlich um verschiedene Objekte. Du möchtest nicht die Eingabeobjekte vergleichen, sondern den Text der vom Benutzer jeweils eingegeben wurde. Den kann man mit einer Methode auf dem `Entry` abfragen oder man verwendet als `text` ein `tkinter.StringVar`-Objekt. An das kann man auch eine Behandlungsfunktion oder -methode binden die immer bei Veränderungen aufgerufen wird.

Beim `Label` in Zeile 18 macht es auch gar keinen Sinn das Ergebnis des `test()`-Aufrufs als Text zu setzen, denn die Funktion hat ja gar kein explizites Ergebnis. Du gibst da überhaupt nichts zurück sondern erstellst ein weiteres `Label` in der GUI. Zusätzlich hat der Benutzer ja noch überhaupt nichts eingegeben. Erst wenn die `mainloop()` läuft hat der Benutzer dazu die Möglichkeit.

Der Auslöser für den Vergleich muss die Eingabetaste im zweiten `Entry` sein. Dafür muss man das entsprechende Ereignis an eine Funktion binden, die dann den Inhalt der beiden `Entry`\s vergleicht, je nach Ergebnis bei einem bereits vorhandenen `Label` den Text ändert, den Fokus auf das erste `Entry` setzt und dort den Text selektiert. Vielleicht auch gleich noch das zweite `Entry` leert.

Beim ersten `Entry` würde ich dann bei jeder Veränderung des Inhalts den Text im Ergebnis-`Label` löschen.

Oder man setzt das Ergebnis-`Label` bei jeder Veränderung eines der beiden `Entry`\s entsprechend. Dann kann man sicher sein, das die Anzeige dort immer korrekt ist.

Unterm Strich ist das zwar nicht viel Quelltext, aber konzeptuell vielleicht nicht ganz so einfach wie Du Dir das vorstellst.

Welche Aufgabe soll das Programm denn lösen?
Eisi
User
Beiträge: 62
Registriert: Sonntag 24. November 2013, 21:59

Danke erstmal für die ausführliche Antwort.

Ja ich denke auch das ich da vielleicht noch nicht soviel mit dem Tkinter machen sollte und mich nochmal auf das python tutorial stürzen sollte.

Es wird ein Strichcode eingescannt welcher z.B. die Zahlen 123456-0100 enthält. Das format ist immer gleich nur die Zahlen ändern sich halt. "xxxxxx-xxxx" x= ziffer

Sind die Codes gleich dann soll auch "Richtig" erscheinen.

Vielleicht verstehe ich es wenn der Code (Nur wenn du willst und du Zeit hast) hier steht und ich ihn mal durchgehen kann.

MfG Christoph
Eisi
User
Beiträge: 62
Registriert: Sonntag 24. November 2013, 21:59

So ich hab mal ein wenig im Internet gesucht und durch ein wenig lesen bin ich nun doch ein ganzes Stück weiter gekommen. Hier mal mein Aktueller und auch teilweise funktionierender Code

Code: Alles auswählen

from tkinter import *

def ausgabe(event):
    if entry1.get() == entry2.get():
        ergebnis.configure(text = "Richtig")
    else:
        ergebnis.configure(text = "Falsch")


w = Tk()
entry1 = Entry(w)
entry1.bind(ausgabe)
entry1.pack()
entry2 = Entry(w)
entry2.bind("<Return>", ausgabe)
entry2.pack()
ergebnis = Label(w)
ergebnis.pack()
w.mainloop()
Jetzt fehlt mir noch das automatische Wechseln der Eingabefelder nach einem "Enter" drücken. Mal schauen :)
BlackJack

@Eisi: Bin zu faul nachzusehen: Die Methode heisst entweder `set_focus()` oder `focus_set()`. :-)
Eisi
User
Beiträge: 62
Registriert: Sonntag 24. November 2013, 21:59

BlackJack hat geschrieben:@Eisi: Bin zu faul nachzusehen: Die Methode heisst entweder `set_focus()` oder `focus_set()`. :-)
focus_set() scheint richtig zu sein. mal gucken wie ich es richtig einbinden muss. Schonmal danke ^^
Eisi
User
Beiträge: 62
Registriert: Sonntag 24. November 2013, 21:59

Code: Alles auswählen

from tkinter import *

def springen1(event):
    if entry1.get() == entry2.get():
        ergebnis.configure(text = "Richtig")
        entry1.focus_set()
    else:
        ergebnis.configure(text = "Falsch")
        entry1.focus_set()

def springen2(event):
    entry2.focus_set()

w = Tk()
entry1 = Entry(w)
entry1.focus_set()
entry1.bind("<Return>", springen2)
entry1.pack()

entry2 = Entry(w)
entry2.bind("<Return>", springen1)
entry2.pack()
ergebnis = Label(w)
ergebnis.pack()
w.mainloop()
Jetzt fehlt noch das Markieren wenn er von der zweiten Reihe in die Erste springt. Vielleicht hat ja noch jemand ein Tip für mich? ^^
Eisi
User
Beiträge: 62
Registriert: Sonntag 24. November 2013, 21:59

Code: Alles auswählen

from tkinter import *

def springen1(event):
    if entry1.get() == entry2.get():
        ergebnis.configure(text = "Richtig")
        entry1.focus_set()
        entry1.delete(0,100)
        
    else:
        ergebnis.configure(text = "Falsch")
        entry1.focus_set()
        entry1.delete(0,100)
        
def springen2(event):
    entry2.delete(0,100)
    entry2.focus_set()

w = Tk()
entry1 = Entry(w)
entry1.focus_set()
entry1.bind("<Return>", springen2)
entry1.pack()

entry2 = Entry(w)
entry2.bind("<Return>", springen1)
entry2.pack()
ergebnis = Label(w)
ergebnis.pack()
w.mainloop()
Ich denke nun funktioniert es ganz gut. Es gibt bestimmt noch andere, vielleicht bessere Varianten aber damit kann ich schonmal leben. Werde nun noch versuchen die Programmgröße (hoffentlich automatisch) an die jeweiligen monitore an zu passen.
BlackJack

@Eisi: Wenn etwas am sowohl am Ende vom ``if``-Zweig als auch am Ende vom ``else``-Zweig gemacht wird, dann kann man das auch nur *einmal* hinter den beiden ausführen.

Statt der 100 würde ich die Konstante `tkinter.END` beim löschen des `Entry`-Inhalts verwenden.
Eisi
User
Beiträge: 62
Registriert: Sonntag 24. November 2013, 21:59

@Blackjack

Beides umgesetzt und funktioniert. Danke nochmal für deine ständigen Tips.

Ich habe es hinbekommen das sich das Programmfenster Automatisch auf die Bildschirmbreite einstellt. Geht das auch mit dem der Textgröße? Sodass entry1, entry2 und ausgabe 33% der größe bekommen? Hier nochmal der aktuelle Code:

Code: Alles auswählen

from tkinter import *

def springen1(event):
    if entry1.get() == entry2.get():
        ergebnis.configure(text = "Richtig", bg = "green", font=('Arial', 200))
        entry1.focus_set()
        
    else:
        ergebnis.configure(text = "Falsch", bg = "red", font=('Arial', 200))
        entry1.focus_set()
    entry1.delete('0',END)
        
def springen2(event):
    entry2.delete(0,100)
    entry2.focus_set()

w = Tk()
title=w.title("Vergleicher")
width=w.winfo_screenwidth()
height=w.winfo_screenheight()
w.geometry(("%dx%d")%(width,height))
entry1 = Entry(w, font=('Arial', 200))
entry1.focus_set()
entry1.bind("<Return>", springen2)
entry1.pack(fill=X)

entry2 = Entry(w, font=('Arial', 200))
entry2.bind("<Return>", springen1)
entry2.pack(fill=X)
ergebnis = Label(w)
ergebnis.pack(fill=X)
w.mainloop()
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

BlackJack hat geschrieben:@Eisi: Wenn etwas am sowohl am Ende vom ``if``-Zweig als auch am Ende vom ``else``-Zweig gemacht wird, dann kann man das auch nur *einmal* hinter den beiden ausführen.
@Eisi: Jetzt schau dir doch noch einmal die Enden deiner if- und else-Blöcke an ;-)

Wenn du nun wieder die letzte Zeile herausgezogen hast wirst du feststellen, dass der Code in beiden Teilen nun fast identisch ist. Dann musst du noch weiter zusammenfassen:

Code: Alles auswählen

def springen1(event):
    if entry1.get() == entry2.get():
        text, background_color = "Richtig", "green"
    else:
        text, background_color = "Falsch", "red"

    ergebnis.configure(text=text, bg=background_color, font=('Arial', 200))
    entry1.focus_set()
    entry1.delete('0',END)
Das Leben ist wie ein Tennisball.
Eisi
User
Beiträge: 62
Registriert: Sonntag 24. November 2013, 21:59

Da war ich wohl zu umständlich :mrgreen: aber ich hoffe das kommt mit der Zeit noch. Habe es verbessert und denke fürs erste wird es funktionieren.

Die nächsten Schritte sind dann, wenn es geht, die Textgröße sich der Bildschirmgröße automatisch anpassen zu lassen und das vergleichen der Eingabe mit dem Inhalt einer anderen Datei.

Für den Beistand und die Hilfe danke ich euch schonmal :wink:
Eisi
User
Beiträge: 62
Registriert: Sonntag 24. November 2013, 21:59

Morgen zusammen.

Ich habe gestern Abend das Programm mit cx freeze auf meinem win7 Rechner als exe erstellt. Nun auf der Rechner auf dem xp rechner sagt er mir das es keine zulässige win 32 Anwendung ist. Was kann ich machen?
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Ich rat mal: ein 32bittiges Python benutzen...
Eisi
User
Beiträge: 62
Registriert: Sonntag 24. November 2013, 21:59

Sirius3 hat geschrieben:Ich rat mal: ein 32bittiges Python benutzen...
Es kann so einfach sein ^^.

Außer einer .dll die er noch brauchte läuft es jetzt auch auf dem XP Rechner. Nun versuche ich mich mal im auslesen anderer daten um das programm noch zu optimieren. Es wird wohl nicht ausbleiben das ich hier nochmal etwas hilfe brauchen werde ^^. Nun ich versuche mich aber erstmal allein dran.

danke euch nochmals
Antworten