Seite 1 von 1

Status-Anzeige wird einfach übersprungen(?)

Verfasst: Montag 30. November 2020, 22:25
von fickAdmiral
Hallo,

ich versuche grade ein simples login mit tkinter zu realisieren. das ganze ist ein frames aufgelteilt. es gibt drei davon:

1) frame_login:
hier ist das login-formular

2) frame_loader:
nach erfolgreichem login müssen noch weitere daten abgefragt werden über eine REST-API, den fortschritt würde ich gerne in diesem frame anzeigen lassen

3) frame_content:
ist alles fertig geladen, wird dieses frame erzeugt

alles funktioniert soweit.. nur bekomme ich das frame_loader nicht zu sehen.. nachdem ich den loginversuch starte kommt direkt das frame_content(?) +vielleicht kann mir jemand sagen was ich falsch mache?

Code: Alles auswählen

from tkinter import *
from tkinter import ttk
from tkinter import font as tkfont 

import requests
from requests.exceptions import HTTPError
import pymysql 
import pprint
import time
import asyncio  


root = Tk()
root.resizable(False, False)
root.title("MyApp")
root.geometry('600x300')

s = ttk.Style()

# - Vars
canvas_width = 600
canvas_height = 100

API_host = "http://examle.com/api/"

# - MySQL
db = pymysql.connect("11.11.11.12","username","password","dbname")
mySqlCursor = db.cursor()


# ---------------------------------------- FRAME login ----------------------------------------
def create_login():

    root.geometry('600x300')

    # create main-frame
    frame_login_content = ttk.Frame(root, padding=(0,0,0,0))       
    
    # create login-form into main-frame
    login_form = ttk.Frame(frame_login_content, padding=(0,1,1,1))    

    labelframeLogin = ttk.LabelFrame(login_form, text = "Please login: ")
    labelframeLogin.pack(expand="yes", padx=15, pady=15)               

    labelUser = ttk.Label(labelframeLogin, text='Usr:') 
    entryUser = ttk.Entry(labelframeLogin)         
    labelPwd = ttk.Label(labelframeLogin, text='Pwd:')  
    entryPwd = ttk.Entry(labelframeLogin)     
       
    button1 = ttk.Button(login_form, text = "Login", width = 20, command = lambda: doLogin(entryUser.get(), entryPwd.get()))
    button1.pack(padx=10, pady=10)

    # layut - grid
    frame_login_content.grid(column=0, row=0, sticky=(N, S, E, W))
    login_canvas.grid(column=0, row=0, sticky=(E, W))
    login_form.grid(column=0, row=1, sticky=(E, W), padx=10, pady=10)


    labelUser.grid(column=1, row=2, sticky=(E, W), padx=10, pady=3)
    entryUser.grid(column=2, row=2, sticky=(E, W), padx=10, pady=3)
    labelPwd.grid(column=1, row=3, sticky=(E, W), padx=10, pady=3)
    entryPwd.grid(column=2, row=3, sticky=(E, W), padx=10, pady=3)

    # weight elements
    root.columnconfigure(0, weight=1)
    root.rowconfigure(0, weight=1)
    frame_login_content.columnconfigure(0, weight=3)
    frame_login_content.columnconfigure(1, weight=3)
    frame_login_content.columnconfigure(2, weight=3)
    frame_login_content.columnconfigure(3, weight=1)
    frame_login_content.columnconfigure(4, weight=1)
    frame_login_content.rowconfigure(1, weight=1)

    return frame_login_content


# ---------------------------------------- FRAME loader ----------------------------------------
def create_loader(msg): 

    global actualFrame

    actualFrame2 = actualFrame
    actualFrame2.destroy()   

    # create main-frame
    frame_loader_content = ttk.Frame(root, padding=(0,0,0,0))   
    actualFrame = frame_loader_content

    login_title = ttk.Label(frame_loader_content, text = "Bitte warten", anchor="center") 
    login_msg = ttk.Label(frame_loader_content, text = msg, anchor="center", foreground = "#666666")

    frame_loader_content.grid(column=0, row=0, sticky=(N, S, E, W), padx=10, pady=10)
    login_title.grid(column=0, row=0, columnspan=5, sticky=(E, W), padx=10, pady=3)
    login_msg.grid(column=0, row=1, columnspan=5, sticky=(E, W), padx=10, pady=3)

    root.geometry('600x80')

    # weight elements
    root.columnconfigure(0, weight=1)
    root.rowconfigure(0, weight=1)
    frame_loader_content.columnconfigure(0, weight=3)  

    return frame_loader_content

   
# ---------------------------------------- FRAME content ----------------------------------------
def create_content():    

    create_loader("Requestion API")

    # - request API
    p = makeRestCall(API_host, {})

   # - check if request worked
    try:   
        request Check = len(p) 

    except:
        create_loader("ERROR - request-JSON is currupt") 

    else:         
        create_loader("request ok")
        contentFrame = buildContentFrame(p)

        return contentFrame
       

# ---------------------------------------- FUNCTIONS ----------------------------------------
def doLogin(u,p):    

    create_loader('Logging in')

    # - Perform login and check result
    # .....
        
    for x in myresult: 
        if x["USERID"]:
            logInCheck = 1 

    if logInCheck == 1: 
        create_loader("Login successfull")
        create_content()
    else:        
        create_login()



# - call first frame 
actualFrame = create_login()

root.mainloop()
ich habe bereits versucht in die funktion create_loader() ein time.sleep(1) einzubringen aber das verzögert einfach nur die wartezeit vom login bis zur anzeige des content-frame.

Re: Status-Anzeige wird einfach übersprungen(?)

Verfasst: Donnerstag 3. Dezember 2020, 08:45
von peterpy
Hallo *Admiral,
wie testest Du deinen Code?
Überprüfe deinen try except Block. Da ist ein Fehler drin.
Vermeide Sternchen Importe. Hier im Forum findest Du die Gründe.
Variablen werden durchwegs klein geschrieben.
Gruss Peter

Re: Status-Anzeige wird einfach übersprungen(?)

Verfasst: Donnerstag 3. Dezember 2020, 09:37
von Sirius3
@fickAdmiral: Du hast eine falsche Vorstellung davon, wie GUIs funktionieren. GUIs sind eventgesteuert, das heißt, dass es einen mainloop gibt, der für jedes Event das Auftritt einen Callback aufruft, der nur kurz etwas tun darf, und dann wieder zur Mainloop zurückkehrt. Für langlaufende Aufgaben braucht man einen Hintergrundthread.

Re: Status-Anzeige wird einfach übersprungen(?)

Verfasst: Donnerstag 3. Dezember 2020, 23:10
von fickAdmiral
peterpy hat geschrieben: Donnerstag 3. Dezember 2020, 08:45 Hallo *Admiral,
wie testest Du deinen Code?
Überprüfe deinen try except Block. Da ist ein Fehler drin.
Vermeide Sternchen Importe. Hier im Forum findest Du die Gründe.
Variablen werden durchwegs klein geschrieben.
Gruss Peter
Hi, danke für die Antwort.
Also ich bin noch weit von unit-testing in python entfernt, wenn du das meinst mit "wie testest Du deinen Code?". Ansonsten teste ich indem ich sehe ob es funktioniert ^^
Ob so oder so, das loader_frame mit einer spezifischen message sollte doch dennoch angezeigt werden(?).

Re: Status-Anzeige wird einfach übersprungen(?)

Verfasst: Donnerstag 3. Dezember 2020, 23:13
von fickAdmiral
Sirius3 hat geschrieben: Donnerstag 3. Dezember 2020, 09:37 @fickAdmiral: Du hast eine falsche Vorstellung davon, wie GUIs funktionieren. GUIs sind eventgesteuert, das heißt, dass es einen mainloop gibt, der für jedes Event das Auftritt einen Callback aufruft, der nur kurz etwas tun darf, und dann wieder zur Mainloop zurückkehrt. Für langlaufende Aufgaben braucht man einen Hintergrundthread.
Hi, danke für den Tipp. Ich versuche das mal event-gesteuert umzuschreiben.

Re: Status-Anzeige wird einfach übersprungen(?)

Verfasst: Freitag 4. Dezember 2020, 08:00
von peterpy
Hallo *Admiral,
Ansonsten teste ich indem ich sehe ob es funktioniert
Da wirst Du aber Zeit mit Fehler suchen verschwenden.
Lass deinen Code zum Testen in Idle laufen, ist doch in Python integriert.
Idle sagt dir auch wo und was für Fehler autreten.
Gruss Peter

Re: Status-Anzeige wird einfach übersprungen(?)

Verfasst: Freitag 4. Dezember 2020, 08:28
von Sirius3
@peterpy: tkinter-Programme darf man nicht in Idle laufen lassen, da Idle auch in Tkinter geschrieben ist und nicht sauber die Ausführung davon trennt. Der Fehler im try-Block ist ein Syntaxfehler, so dass das Programm erst gar nicht am Compiler vorbeikommt.
makeRestCall ist gar nicht definiert, wie so einiges andere nicht definiert ist.

@fickAdmiral: wenn Du anfängst, etwas umzuschreiben, dann fange gleich auch an, dich an die Konventionen zu halten: benutze keine *-Importe, Konstanten werden komplett gross geschrieben, Variablennamen und Funktionen dagegen komplett klein. Es darf kein ausführbaren Code auf oberster Ebene geben, es darf keine globalen Variablen geben und vor Du mit GUIs anfängst mußt Du Klassen einigermaßen beherrschen, denn ohne Klassendefinitionen kannst Du kein sauberes GUI-Programm schreiben.

Re: Status-Anzeige wird einfach übersprungen(?)

Verfasst: Samstag 5. Dezember 2020, 23:24
von fickAdmiral
Sirius3 hat geschrieben: Freitag 4. Dezember 2020, 08:28 @peterpy: tkinter-Programme darf man nicht in Idle laufen lassen, da Idle auch in Tkinter geschrieben ist und nicht sauber die Ausführung davon trennt. Der Fehler im try-Block ist ein Syntaxfehler, so dass das Programm erst gar nicht am Compiler vorbeikommt.
makeRestCall ist gar nicht definiert, wie so einiges andere nicht definiert ist.
die funktionen sind schon da :) ich habe sie hier im beispiel weggelassenl, um den code nicht unnötig aufzublähen. eine makeRestCall() macht ja nichts ausser http-request und ergebniss wieder zurückgeben.
Sirius3 hat geschrieben: Freitag 4. Dezember 2020, 08:28 @fickAdmiral: wenn Du anfängst, etwas umzuschreiben, dann fange gleich auch an, dich an die Konventionen zu halten: benutze keine *-Importe, Konstanten werden komplett gross geschrieben, Variablennamen und Funktionen dagegen komplett klein. Es darf kein ausführbaren Code auf oberster Ebene geben, es darf keine globalen Variablen geben und vor Du mit GUIs anfängst mußt Du Klassen einigermaßen beherrschen, denn ohne Klassendefinitionen kannst Du kein sauberes GUI-Programm schreiben.
Ich werde es beherzigen. Aber auch keine camelCase in python?

Re: Status-Anzeige wird einfach übersprungen(?)

Verfasst: Montag 7. Dezember 2020, 05:25
von Nufnus
fickAdmiral hat geschrieben: Samstag 5. Dezember 2020, 23:24 Aber auch keine camelCase in python?
Ohne Gewähr, ich versuch mir das auch erst alles anzueignen, aber falls mir niemand widerspricht habe ich es vermutlich richtig verstanden ^^
Dein Beispiel ist lower camel case (um genau zu sein). Bei upper camel case wären dann beide Cs groß, also so: CamelCase
lower camel case nennt man in Python mixedCase

Im PEP 8 Styleguide steht dazu:
Function and Variable Names

Function names should be lowercase, with words separated by underscores as necessary to improve readability.

Variable names follow the same convention as function names.

mixedCase is allowed only in contexts where that's already the prevailing style (e.g. threading.py), to retain backwards compatibility.
Ich würde also sagen: Nein. Es sei denn die anderen machen es auch :mrgreen:

Re: Status-Anzeige wird einfach übersprungen(?)

Verfasst: Montag 7. Dezember 2020, 06:02
von __blackjack__
Wobei das Beispiel was da im PEP8 noch erwähnt wird im Grunde keines mehr ist, denn `threading` bietet mittlerweile auch PEP8-konforme Namen. PySerial und BeautifulSoup wären zwei beliebte externe Bibliotheken die auch von dasIstHaesslich auf das_ist_wunderschoen wechseln. Der Trend geht also in Richtung PEP8. 🙂