• 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?

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
0 głosów
1,309 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 (256,320 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 (256,320 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 (256,320 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 (256,320 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ź 239 wizyt
pytanie zadane 1 października 2022 w Python przez MarcelM Początkujący (410 p.)
0 głosów
0 odpowiedzi 309 wizyt
0 głosów
0 odpowiedzi 1,098 wizyt

93,195 zapytań

142,211 odpowiedzi

322,058 komentarzy

62,519 pasjonatów

Advent of Code 2024

Top 15 użytkowników

  1. 3316p. - dia-Chann
  2. 3251p. - Łukasz Piwowar
  3. 3243p. - Łukasz Eckert
  4. 3222p. - CC PL
  5. 3167p. - Tomasz Bielak
  6. 3157p. - Łukasz Siedlecki
  7. 3133p. - rucin93
  8. 3110p. - Maurycy W
  9. 3028p. - Adrian Wieprzkowicz
  10. 2992p. - Mikbac
  11. 2490p. - Marcin Putra
  12. 2467p. - Michał Telesz
  13. 2427p. - Michal Drewniak
  14. 2372p. - Anonim 3619784
  15. 1949p. - rafalszastok
Szczegóły i pełne wyniki

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

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...