主要相關代碼在EntryForm 類(第 190 行左右)和BookmarkAccess 類(第 246 行左右)中
在登錄完成后,我共享全域 user_id作為從資料庫中查詢特定資料行的一種方式。
我當前的解決方法是使用最后一頁上的按鈕,使用啟動后生成的 user_id 來填充串列框(self.title.select)。
我嘗試了以下無濟于事:在 EntryForm 中繼承 BookmarkAccess 并在此處通過按鈕命令傳遞小部件創建。還嘗試在沒有 user_id 限制的情況下決議應用啟動時的完整查詢,然后僅使用相關的 user_id 填充串列框,但我也無法正常作業。
我想做的是在某個先前的螢屏上(例如,在登錄并傳遞更新的全域 user_id 后立即),填充最終的串列框(self.title_select),所以當我訪問該頁面時,串列框已經充滿了預期的查詢行.
任何幫助或指導將不勝感激。
import sqlite3 as sql
import tkinter as tk
import tkinter.ttk as ttk
BASE_FONT = ("Bookman Old Style", 10)
user_id = None
class Database:
def __init__(self, *args, **kwargs):
self.connection = sql.connect("testing.db")
self.cursor = self.connection.cursor()
try:
self.cursor.execute(
"""CREATE TABLE IF NOT EXISTS users
(username TEXT NOT NULL UNIQUE,
password TEXT NOT NULL)
;"""
)
self.connection.commit()
except sql.OperationalError:
pass
try:
self.cursor.execute(
"""CREATE TABLE IF NOT EXISTS bookmarks
(OwnerID INTEGER NOT NULL,
Title TEXT NOT NULL,
Link TEXT NOT NULL)
;"""
)
self.connection.commit()
except sql.OperationalError:
pass
def add_account(self, username, password):
self.cursor.execute("""INSERT INTO users VALUES (?,?)""", (username, password))
self.connection.commit()
def login_func(self, username, password):
self.cursor.execute("SELECT password FROM users WHERE username = (?)", (username,))
result = str(self.cursor.fetchone()).strip("'(),")
print(result)
if result == password:
print("true")
return True
else:
print("false")
return False
def get_user_id(self, username):
self.cursor.execute("SELECT rowid FROM users WHERE username = (?)", (username,))
cleaned_id = str(self.cursor.fetchone()).strip(" ( , ) ")
return int(cleaned_id)
def commit_bookmark(self, active_id, title, link):
if len(title) and len(link) != 0:
self.cursor.execute("""INSERT INTO bookmarks (OwnerID,Title,Link)
VALUES (?,?,?)""", (active_id, title, link,))
self.connection.commit()
else:
print("nothing to bookmark")
def title_populate(self, active_id):
self.cursor.execute("SELECT Title FROM bookmarks WHERE OwnerID = (?)", (active_id,))
return self.cursor.fetchall()
def bookmarks_by_title(self, param, active_id):
self.cursor.execute("SELECT Title FROM bookmarks WHERE Title LIKE (?) AND OwnerID=(?)",
('%' param '%', active_id,))
return self.cursor.fetchall()
db = Database()
# complete
class LoginInterface(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
button_styling = ttk.Style()
button_styling.configure("my.TButton", font=BASE_FONT)
label_styling = ttk.Style()
label_styling.configure("my.TLabel", font=BASE_FONT)
tk.Tk.wm_title(self, "Login Screen")
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (Login,
CreateNew,
EntryForm,
BookmarkAccess):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(Login)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
# complete
class Login(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.label1 = ttk.Label(self, text="Username: ", style="my.TLabel")
self.label1.grid(row=1, column=1)
self.username = ttk.Entry(self)
self.username.grid(row=1, column=2)
self.label2 = ttk.Label(self, text="Password: ", style="my.TLabel")
self.label2.grid(row=2, column=1, pady=10)
self.password = ttk.Entry(self, show="*")
self.password.grid(row=2, column=2, pady=10)
def login_call(event):
if db.login_func(self.username.get(), self.password.get()) is False:
print("failed validation")
else:
print("validation passed")
global user_id
user_id = db.get_user_id(self.username.get())
controller.show_frame(EntryForm)
self.login = ttk.Button(
self, text="Login", style="my.TButton", command=lambda: login_call(Login))
self.login.grid(row=3, column=2)
self.create_new = ttk.Button(
self,
text="Create New Account",
style="my.TButton",
command=lambda: controller.show_frame(CreateNew),
)
self.create_new.grid(row=4, column=2, pady=10)
# complete
class CreateNew(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.label1 = ttk.Label(self, text="Set Username:", style="my.TLabel")
self.label1.grid(row=1, column=1)
self.username = ttk.Entry(self)
self.username.grid(row=1, column=2)
self.label2 = ttk.Label(self, text="Set Password:", style="my.TLabel")
self.label2.grid(row=2, column=1, padx=5, pady=5)
self.password = ttk.Entry(self)
self.password.grid(row=2, column=2)
self.create_button = ttk.Button(
self,
text="Complete New Account",
style="my.TButton",
command=lambda: db.add_account(self.username.get(), self.password.get()),
)
self.create_button.grid(row=3, column=2, padx=5, pady=5)
self.home = ttk.Button(
self,
text="Go to Login",
style="my.TButton",
command=lambda: controller.show_frame(Login),
)
self.home.grid(row=5, column=2, padx=5, pady=5)
# functional
class EntryForm(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
# FIXME
def view_bookmarks(event):
print(user_id)
# BookmarkAccess.title_query = db.title_populate(user_id)
# BookmarkAccess.title_choices = tk.StringVar(value=BookmarkAccess.title_query)
# BookmarkAccess.title_select = tk.Listbox(self, listvariable=BookmarkAccess.title_choices)
# BookmarkAccess.title_select.grid(row=2, column=0, padx=5, pady=10)
controller.show_frame(BookmarkAccess)
def add_bookmark(event):
print(user_id)
db.commit_bookmark(user_id, self.title.get(), self.link.get(), )
self.title.delete(0, tk.END)
self.link.delete(0, tk.END)
self.title_label = ttk.Label(self, text="Title: ")
self.title_label.grid(row=0, column=0)
self.link_label = ttk.Label(self, text="Link: ")
self.link_label.grid(row=0, column=1)
self.title = ttk.Entry(self)
self.title.grid(row=1, column=0, padx=5, pady=10)
self.link = ttk.Entry(self)
self.link.grid(row=1, column=1, padx=5, pady=10)
self.view_bookmarks = ttk.Button(
self,
text="View Bookmarks",
style="my.TButton",
command=lambda: view_bookmarks(Login),
)
self.view_bookmarks.grid(row=5, column=1)
self.commit_new_bookmark = ttk.Button(
self,
text="Add Bookmark",
style="my.TButton",
command=lambda: add_bookmark(Login),
)
self.commit_new_bookmark.grid(row=2, column=1)
# functional
class BookmarkAccess(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.title_label = ttk.Label(self, text="Filter by Title: ")
self.title_label.grid(row=0, column=0)
# title filter: entry box
self.title_filter = ttk.Entry(self)
self.title_filter.grid(row=1, column=0, padx=5, pady=10)
# FIXME
self.title_select = tk.Listbox(self)
self.title_select.grid(row=3, column=0, padx=5, pady=10)
# title filter
def title_filtering(event):
self.title_select.destroy()
self.title_query = db.bookmarks_by_title(self.title_filter.get(), user_id)
self.title_choices = tk.StringVar(value=self.title_query)
self.title_select = tk.Listbox(self, listvariable=self.title_choices)
self.title_select.grid(row=3, column=0, padx=5, pady=10)
self.title_filter.bind('<Return>', title_filtering)
self.title_button = ttk.Button(self, style='my.TButton', text="Filter Title",
command=lambda: title_filtering(Login))
self.title_button.grid(row=2, column=0, padx=5, pady=10)
app = LoginInterface()
app.mainloop()
uj5u.com熱心網友回復:
建議使用 tkinter 虛擬事件通知引發的框架,以便框架在接收到該虛擬事件時可以執行一些操作:
class LoginInterface(tk.Tk):
...
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
frame.event_generate('<<Raised>>') # notify frame
然后修改BookmarkAccess以在接收到虛擬事件時填充串列框:
class BookmarkAccess(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.title_label = ttk.Label(self, text="Filter by Title: ")
self.title_label.grid(row=0, column=0)
# title filter: entry box
self.title_filter = ttk.Entry(self)
self.title_filter.grid(row=1, column=0, padx=5, pady=10)
self.title_choices = tk.StringVar()
self.title_select = tk.Listbox(self, listvariable=self.title_choices)
self.title_select.grid(row=3, column=0, padx=5, pady=10)
self.title_filter.bind('<Return>', self.title_filtering)
self.title_button = ttk.Button(self, style='my.TButton', text="Filter Title",
command=self.title_filtering)
self.title_button.grid(row=2, column=0, padx=5, pady=10)
self.bind('<<Raised>>', self.title_filtering) # respond virtual event
# title filter
def title_filtering(self, event=None):
self.title_query = db.bookmarks_by_title(self.title_filter.get(), user_id)
self.title_choices.set(self.title_query)
請注意,我已將嵌套函式更改title_filtering()為類方法 ID 順序,以便在不同情況下使用。還要更改以更新串列框而不是銷毀它并重新創建新的串列框。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/443854.html
標籤:Python sql python-3.x sqlite tkinter
上一篇:如何從外部檔案的類函式呼叫returnTrue或retutrnFalse?
下一篇:如何在裝飾器中傳遞帶有值的變數?
