• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Tkinter, Python - jak zrobić nowe okienko, które wyświetla się po wciśnięciu jakiegoś przycisku?

Object Storage Arubacloud
0 głosów
849 wizyt
pytanie zadane 20 listopada 2022 w Python przez stachu2822 Nowicjusz (160 p.)

Witam serdecznie,

robię prosty, graficzny emulator systemu operacyjnego w pythonie, korzystajac z tkintera.

Problem znajduje się w 37 linijce - nie wiem jak zrobić następującą czynność:

wprowadzam swoją nazwę użytkownika, i chcę, żeby dwie sekundy po tym pojawiło się nowe okienko, w którym wprowadzam swoje hasło. Wydaje mi się, że można zrobić to funkcją if, ale nie wiem jaki warunek tam postawić.

Z góry dziękuję za pomoc.

import time
from time import sleep
from tkinter import *
from PIL import ImageTk, Image
from tkinter import filedialog



root = Tk()
root.title("QOS")
root.iconbitmap("C:\pythonfiles\icofile.ico")
root.geometry("640x360")



usrEntry = Entry(root, width=50)
usrEntry.pack()
usrEntry.insert(0, "Wpisz swoją nazwę użytkownika: ")



def usr_enter():
    usr = Label(root, text="Witamy w QOS, " + usrEntry.get())
    usr.pack()

usrConfirm = Button(
    root,
    text="Zaakceptuj swoją nazwę użytkownika klikając w przycisk",
    padx=5, pady=20,
    activebackground="#959595",
    command=usr_enter
)

usrConfirm.pack()

if  # problem znajduje sie tutaj
    password = Toplevel()
    sleep(2)
    psw_enter = Label(password, text="czesc").pack()

root.mainloop()

 

 

1 odpowiedź

0 głosów
odpowiedź 21 listopada 2022 przez VBService Ekspert (253,300 p.)
edycja 21 listopada 2022 przez VBService

W takiej formie jak zapisałeś nie da nic się wpisać w if-a bo kod w ten sposób umieszczony wykona się po inicjalizacji okna, a tu mamy do czynienia z poczekaniem na zdarzenie (event) np. wpisania nazwy użytkownika lub kliknięcia w przycisk usrConfirm w takim wypadku ten kod

    password = Toplevel()
    sleep(2)
    psw_enter = Label(password, text="czesc").pack()

powinien być przeniesiony do

def usr_enter():
    usr = Label(root, text="Witamy w QOS, " + usrEntry.get())
    usr.pack()

    password = Toplevel()
    sleep(2)
    psw_enter = Label(password, text="czesc").pack()

i wtedy można np. zapisać tak

def usr_enter():
    usr = Label(root, text="Witamy w QOS, " + usrEntry.get())
    usr.pack()

    if len(usrEntry.get()) > 2: #więcej niż 2 znaki
        password = Toplevel()
        sleep(2)
        psw_enter = Label(password, text="czesc").pack()

 

 

Może przenieś całe logowanie do okienka (popup - dialog modal). W przykładzie zakładam, że są utworzone 2 konta (symulacja: lista users)

from datetime import datetime
from time import sleep
from tkinter import *
from PIL import ImageTk, Image
from tkinter import filedialog


def log_time():
    return f"[{datetime.now():%x %X}]"


root = Tk()
root.title("QOS")
root.iconbitmap("C:\pythonfiles\icofile.ico")
root.geometry("640x360")
 
users = ["stachu2822", "VBService"] 

def list_of_users():
    frame = Frame(root)
    frame.pack()
    button_row = 1
    for user in users:
        userButton = Button(
            frame,
            text=user,
            width=20, padx=5, pady=5,
            highlightcolor="green",
            activebackground="#959595",
            font="Consolas 10",
            command=lambda user=user: popup_user_login(user)
        )
        button_row += 1
        userButton.grid(column=0, row=button_row)
        
def popup_user_login(user):
    def close_popup_user_login(): # naciśnięto przycisk x w okienku
        print("User", user, "anulował logowanie", log_time())
        # zamykanie okna popup
        root.wm_attributes("-disabled", False)
        popup.destroy()
        root.deiconify()
        
    def user_login(): # naciśnięto przycisk Login
        print("   Login:", userLoginEntry.get())
        print("Password:", userPasswordEntry.get())

    # otwieranie okna popup    
    root.wm_attributes("-disabled", True)
    popup = Toplevel(root)
    popup.transient(root)
    popup.protocol("WM_DELETE_WINDOW", close_popup_user_login)
    popup.minsize(250, 120)
    popup.maxsize(250, 120)
    popup.title("Login")
    popup.tkraise(root)
            
    Label(popup, text="Podaj login:").pack()
    userLoginEntry = Entry(popup, width=50)
    userLoginEntry.insert(0, user)
    userLoginEntry.pack()    
    Label(popup, text="Podaj hasło:").pack()
    userPasswordEntry = Entry(popup, width=50)
    userPasswordEntry.pack()
    Button(popup, text="Login", font="Consolas 10",
           width=20, padx=5, pady=5, command=user_login).pack(pady=10)

    popup.mainloop()


if __name__ == "__main__":
    list_of_users()
    root.mainloop()

 

komentarz 21 listopada 2022 przez stachu2822 Nowicjusz (160 p.)

Serdecznie dziękuję za odpowiedź, 

zastanawiam się jednak, czy poniższy skrawek kodu mogę wykorzystać cały czas, bez większych zmian i dalej będzie on działał? (inaczej: czy ten, niezmieniony, kawałek kodu cały czas będzie dawał oczekiwane rezultaty, nawet przy innych programach (oczywiście zmieniamy wszelkie zmienne itp.)

# otwieranie okna popup
    root.wm_attributes("-disabled", True)
    popup = Toplevel(root)
    popup.transient(root)
    popup.protocol("WM_DELETE_WINDOW", close_popup_user_login)
    popup.minsize(250, 120)
    popup.maxsize(250, 120)
    popup.title("Login")
    popup.tkraise(root)

    Label(popup, text="Podaj login:").pack()
    userLoginEntry = Entry(popup, width=50)
    userLoginEntry.insert(0, user)
    userLoginEntry.pack()
    Label(popup, text="Podaj hasło:").pack()
    userPasswordEntry = Entry(popup, width=50)
    userPasswordEntry.pack()
    Button(popup, text="Login", font="Consolas 10",
           width=20, padx=5, pady=5, command=user_login).pack(pady=10)

 

komentarz 21 listopada 2022 przez VBService Ekspert (253,300 p.)
edycja 21 listopada 2022 przez VBService

Właściwie to musisz wziąć ten cały kod

def popup_user_login(user):
    def close_popup_user_login(): # naciśnięto przycisk x w okienku
        print("User", user, "anulował logowanie", log_time())
        # zamykanie okna popup
        root.wm_attributes("-disabled", False)
        popup.destroy()
        root.deiconify()
         
    def user_login(): # naciśnięto przycisk Login
        print("   Login:", userLoginEntry.get())
        print("Password:", userPasswordEntry.get())

        '''
        # np. gdy login i password OK wtedy
        if userLoginEntry.get() == "stachu2822" and
           userPasswordEntry.get() == "1234":
           root.wm_attributes("-disabled", False) popup.destroy() 
           root.deiconify()
        '''        
 
    # otwieranie okna popup    
    root.wm_attributes("-disabled", True)
    popup = Toplevel(root)
    popup.transient(root)
    popup.protocol("WM_DELETE_WINDOW", close_popup_user_login)
    popup.minsize(250, 120)
    popup.maxsize(250, 120)
    popup.title("Login")
    popup.tkraise(root)
             
    Label(popup, text="Podaj login:").pack()
    userLoginEntry = Entry(popup, width=50)
    userLoginEntry.insert(0, user)
    userLoginEntry.pack()    
    Label(popup, text="Podaj hasło:").pack()
    userPasswordEntry = Entry(popup, width=50)
    userPasswordEntry.pack()
    Button(popup, text="Login", font="Consolas 10",
           width=20, padx=5, pady=5, command=user_login).pack(pady=10)
 
    popup.mainloop()

z obsługą zamykania okna popup (dialog modal)

ta cześć kodu jest zmienna to są elementy (label, textinput, button itp.) w oknie popup

    Label(popup, text="Podaj login:").pack()
    userLoginEntry = Entry(popup, width=50)
    userLoginEntry.insert(0, user)
    userLoginEntry.pack()    
    Label(popup, text="Podaj hasło:").pack()
    userPasswordEntry = Entry(popup, width=50)
    userPasswordEntry.pack()
    Button(popup, text="Login", font="Consolas 10",
           width=20, padx=5, pady=5, command=user_login).pack(pady=10)

 

komentarz 21 listopada 2022 przez VBService Ekspert (253,300 p.)

Okno popup jest "wywoływane" otwierane przez kliknięcie w tym przypadku button-a

    for user in users:
        userButton = Button(
            frame,
            text=user,
            width=20, padx=5, pady=5,
            highlightcolor="green",
            activebackground="#959595",
            font="Consolas 10",
            command=lambda user=user: popup_user_login(user)
        )

 

komentarz 21 listopada 2022 przez stachu2822 Nowicjusz (160 p.)

Gdybyś mógł jeszcze wytłumaczyć co robią poszczególne linijki, które zawarłem niżej, byłbym wdzięczny

acc.wm_attributes("-disabled", True) # dokładniej ta
    popup = Toplevel(root)
    popup.transient(root) # i ta
    popup.protocol("WM_DELETE_WINDOW", close_popup_user_login) # i ta
    popup.minsize(250, 120)
    popup.maxsize(250, 120)
    popup.title("Login")
    popup.tkraise(root)

 

komentarz 21 listopada 2022 przez VBService Ekspert (253,300 p.)
edycja 21 listopada 2022 przez VBService

win.wm_attributes (Window Manager (wm) attributes)

 

wyłączenie okna z którego zostało otwarte popup, np. okno główne nie reaguje na kliknięcia

root.wm_attributes("-disabled", True

 

Jest to metoda Tkintera używana do kojarzenia okna potomnego (child - popup) z oknem nadrzędnym (parent - root). Np. gdy klikniesz w root to popup - zmineina na chwilę kolor w title (i słychać systemową melodyjkę - warring) - flash - sygnalizuje, że jest potomkiem klikanego okna

popup.transient(root)

 

Przechwycenie zdarzenia, że kliknięto przycisk na oknie

 popup.protocol("WM_DELETE_WINDOW", close_popup_user_login)

    def close_popup_user_login(): # naciśnięto przycisk x w okienku
        print("User", user, "anulował logowanie", log_time())
        # zamykanie okna popup
        root.wm_attributes("-disabled", False)
        popup.destroy()
        root.deiconify()

 

Podobne pytania

0 głosów
1 odpowiedź 193 wizyt
pytanie zadane 1 października 2022 w Python przez MarcelM Początkujący (340 p.)
0 głosów
0 odpowiedzi 240 wizyt
0 głosów
0 odpowiedzi 921 wizyt

92,568 zapytań

141,420 odpowiedzi

319,620 komentarzy

61,954 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...