簡體   English   中英

如何在Tkinter中使窗口連續運行? (Python 2.7.11)

[英]How can I make windows in Tkinter that run in succession? (Python 2.7.11)

我希望首先彈出一個登錄窗口,然后在滿足條件后關閉登錄窗口並打開一個新窗口。

from Tkinter import *
import tkMessageBox

#Not really sure what i'm doing here anymore

while True:

    Login = Tk()
    Login.title('Login')
    Login.geometry('400x130')

    NameLabel = Label(Login, text='Username')
    NameLabel.place(bordermode=OUTSIDE, height=25, width=100, x=100)

    NameEntryRaw = Entry(Login)
    NameEntryRaw.place(bordermode=OUTSIDE, height=25, width=100, x=200)

    CodeLabel = Label(Login, text='Code')
    CodeLabel.place(bordermode=OUTSIDE, height=25, width=100, x=100, y=30)

    CodeEntryRaw = Entry(Login)
    CodeEntryRaw.place(bordermode=OUTSIDE, height=25, width=100, x=200, y=30)

    def tbd():

        tkMessageBox.showinfo('Congrats!', 'This program is not done yet')

    def login():

        Usernames=list()
        Usernames.append('Mordecai')
        Usernames.append('Ezekiel')
        Usernames.append('Goliath')
        Usernames.append('Abraham')
        Usernames.append('Bartholomew')
        Usernames.append('Jedediah')
        Usernames.append('Solomon')
        Usernames.append('Tobias')
        Usernames.append('Yohanan')
        Usernames.append('Lucifer')

        NameEntry=NameEntryRaw.get()
        CodeEntry=CodeEntryRaw.get()

        CodeReal='116987'

        if Usernames.count(NameEntry) == 0:
            tkMessageBox.showinfo('Error!', 'Your Username is invalid! Try Again.')

        else:
            ()

        if CodeEntry != CodeReal:
            tkMessageBox.showinfo('Error!', 'The Code entered is invalid! Try Again.')

        else:
            ()     

    LoginButton = Button(Login, text="Login", command=login)
    LoginButton.place(bordermode=OUTSIDE, height=50, width=200, x=100, y=60)
    Login.mainloop()

else:

    DataBase = Tk()
    #this will be the data base
    DataBase.mainloop()

您不想使用兩個mainloop 一般來說,您的.mainloop應用程序應該有一個.mainloop調用。

至於如何獲取登錄彈出窗口,然后切換到窗口...您可以使用該應用創建根窗口,並且在啟動程序時會在Toplevel窗口中顯示登錄內容,或者隱藏/撤消根目錄?,使頂層具有“提交”按鈕或用於驗證憑據的內容。 如果憑據有效,則可以使用destroy()方法並刪除頂級窗口小部件/轉到主應用程序的根窗口。

出於某些明顯原因,讓while True重復創建GUI + mainloop的過程很糟糕。

編輯 :靜態可能是可變對象的壞詞,因為它是可變的...添加了元組vs全局列表。

您無需創建空白列表,然后使用append將用戶名添加到usernames列表中。 您可以將此設置為全局。 由於用戶名是一個可變對象(它是一個列表),您仍然可以在此全局代碼中的其他位置執行操作,例如.append等。或者,如果您從未進行過這些更改,我將其設為元組,因為它們是不變的,這更符合意圖。

無需使用.count(*)來獲取列表中某個元素的出現,您可以使用:

if (object) in (some list) #Object is an abstraction, not the type

如果CodeReal是靜態的(看起來是靜態的),則也可以將其設置為全局。

這是對代碼的快速編輯,您可以在不使用類的情況下執行此操作,但是我在這里使用類來試圖清楚地顯示程序中的邏輯分離。

我還更改了一些變量名,以便於閱讀/理解。 我還使用了.pack().grid()因為這比必須在任意選擇位置都使用.place()速度更快。

import Tkinter as tk 
import tkMessageBox as messagebox
import sys

#No need to do usernames = list() and then .append for each one.
#Just make a global list holding them all...
USERNAMES = ('Mordecai', 'Ezekiel', 'Goliath', 'Abraham', 'Bartholomew',
    'Jedediah', 'Solomon', 'Tobias', 'Yohanan', 'Lucifer')
PASSWORD = '116987' #Was CodeReal, this can be global

#We overrode the closing protocol here.
def closing_protocol():

    if messagebox.askokcancel("Quit", "Do you want to quit?"):
        sys.exit()

#A container for our Login "app".
class Login(tk.Toplevel):

    def __init__(self, *args, **kwargs):

        #We init the toplevel widget.
        tk.Toplevel.__init__(self, *args, **kwargs)

        #We set the closing protocol to be the overridden version / func.
        self.wm_protocol("WM_DELETE_WINDOW", closing_protocol)
        tk.Label(self, text='Username').grid(row=0, column=0)
        self.username = tk.Entry(self)
        self.username.grid(row=0, column=1)

        tk.Label(self, text='Password').grid(row=1, column=0)
        #Show = '*' just hides the password instead of plain-text like
        #you typically see
        self.password = tk.Entry(self, text='Password', show='*')
        self.password.grid(row=1, column=1)

        #When the button is clicked the _callback function will be called
        tk.Button(self, text='Login', command=self._callback).\
            grid(row=2, column=0, columnspan=2, sticky="nsew")

    def _callback(self):

        #If the username or password is bad, raise an error message.
        if (self.username.get() not in USERNAMES or 
            self.password.get() != PASSWORD):
            messagebox.showerror("Validation Error!", 
                "You have entered invalid credentials.\n" +
                "Please try again.")

        #otherwise, we're good to go. Destroy login / show main app.
        else:
            root.deiconify()
            app.pack()
            self.destroy()

class Main(tk.Frame):

    def __init__(self, master):

        tk.Frame.__init__(self, master)
        tk.Label(self, text="MAIN APP STUFF").pack()

if __name__ == '__main__':

    root = tk.Tk()
    root.withdraw() #Hides the root window initially.
    app = Main(root)
    Login()
    root.mainloop()

我要感謝您澄清您為我所做的事情。 事實證明這是非常有幫助的! 這就是我已經解決的問題。 我放回了名稱,使它可以不使用類而工作,因為我發現使用它有點困難。

from Tkinter import *
import tkMessageBox 
import sys
import binascii #Not for this part

Codenames = ['Mordecai', 'Ezekiel', 'Goliath', 'Abraham', 'Bartholomew',
    'Jedediah', 'Solomon', 'Tobias', 'Yohanan', 'Lucifer']

Password = '116987' 

def close_protocol():
    if tkMessageBox.askokcancel("Quit", "Do you want to quit?"):
        sys.exit()
#Below for a later part...
def text_to_bits(text, encoding='utf-8', errors='surrogatepass'):
    bits = bin(int(binascii.hexlify(text.encode(encoding, errors)), 16))[2:]
    return bits.zfill(8 * ((len(bits) + 7) // 8))

def text_from_bits(bits, encoding='utf-8', errors='surrogatepass'):
    n = int(bits, 2)
    return int2bytes(n).decode(encoding, errors)

def int2bytes(i):
    hex_string = '%x' % i
    n = len(hex_string)
    return binascii.unhexlify(hex_string.zfill(n + (n & 1)))
#Above for a later part...
SDB = Tk()
SDB.title("SMEGJALBYT DATA BASE")
SDB.withdraw()

SDBLogin = Toplevel()
SDBLogin.title("Login")

SDBLogin.wm_protocol("WM_DELETE_WINDOW", close_protocol)

CodenameLabel = Label(SDBLogin, text="Codename")
CodenameLabel.grid(row=0, column=0)

CodenameEntry = Entry(SDBLogin)
CodenameEntry.grid(row=0, column=2)

PasswordLabel = Label(SDBLogin, text="Password")
PasswordLabel.grid(row=1, column=0)

PasswordEntry = Entry(SDBLogin, show='*')
PasswordEntry.grid(row=1, column=2)

def login_operation():
    if CodenameEntry.get() not in Codenames:
        tkMessageBox.showinfo("INVALID CODENAME!", "Please verify input in the 'Codename' field")

    elif PasswordEntry.get() != Password:
        tkMessageBox.showinfo("INVALID PASSWORD!", "Please verify input in   the 'Password' field")

    else:
        SDB.deiconify()
        SDBLogin.destroy()

LoginButton = Button(SDBLogin, text="Login", command=login_operation)
LoginButton.grid(row=2, column=1)
#Code continues...
#Code finisles....
SDB.mainloop()

它具有相同的基本功能,只是按照我想要的方式進行組織。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM