[英]Python Tkinter with classes
嘗試開發用於工作的應用程序,我想將UI和主控制器類代碼分開。 我應該如何處理?
我創建了MainUi類。
class MainUi:
store_number = ''
tld_date = ''
def __init__(self, root):
self.root = root
root.title("TacoBell TLD Tool")
self.store_number = IntVar()
self.tld_date = IntVar()
self.lblstore_number = Label(root, text="Store Number (XXXXXX): ")
self.lbltld_date = Label(root, text="TLD Date(MM/DD/YYYY): ")
self.lblstore_number.grid(row=0, sticky=E) # Sticky align text North(N), East(E), South(S), West(W0
self.lbltld_date.grid(row=1, sticky=E)
self.entStore = Entry(self.root, textvariable=self.store_number)
self.entDate = Entry(self.root, textvariable=self.tld_date)
self.entStore.grid(row=0, column=1)
self.entDate.grid(row=1, column=1)
我需要定義getter和setter嗎? 我希望這些條目存儲在我的主類中的兩個變量中,以便我可以將主類中的變量傳遞給其他函數。
import paramiko
import os
import csv
import tools
from ui import MainUi
from tkinter import *
root = Tk()
ui = MainUi(root)
# get store number and date data from UI.py and store them as variables here
root.mainloop()
是的,您可以通過更改類變量store_number
和tld_date
來使它們分開。 為此,您需要從輸入框中獲取數字並將其另存為變量。 我們可以通過調用self.store_number = self.entStore.get()
或self.tld_date = self.entDate.get()
來方便地完成此操作
from tkinter import *
class LaunchMainUi:
store_number = ''
tld_date = ''
def __init__(self, root):
self.root = root
root.title("TacoBell TLD Tool")
self.store_number = IntVar()
self.tld_date = IntVar()
Label(root, text="Store Number (XXXXXX): ").grid(row=0, sticky=E) # Sticky align text North(N), East(E), South(S), West(W)
Label(root, text="TLD Date(MM/DD/YYYY): ").grid(row=1, sticky=E)
self.entStore = Entry(self.root)
self.entDate = Entry(self.root)
self.entStore.grid(row=0, column=1)
self.entDate.grid(row=1, column=1)
self.confirm = Button(root, text="Confirm", command=self.save)
self.confirm.grid(row=2, column=1)
def save(self, event=None):
storeNumber = self.entStore.get()
tldDate = self.entDate.get()
#Saved as method variables ^ in order to perform necessary validation checks easier
#If entered items are valid:
self.store_number = storeNumber
self.tld_date = tldDate
self.root.destroy()
我首先更改了類的名稱,以使文件名和類名不沖突。 然后,我創建了一個名為self.confirm
的按鈕,並將其命令設置為self.save
。 在將類變量設置為所輸入的值並銷毀根窗口之前,此函數將兩個變量存儲為storeNumber
和tldDate
。
import MainUI
from tkinter import *
root = Tk()
ui = MainUI.LaunchMainUi(root)
root.mainloop() #Keeps the ui instance running until closed, then the rest of the code is run
storeNum = ui.store_number
tldDate = ui.tld_date
print('Store Number: {}\nTLD Date: {}'.format(storeNum, tldDate)) #This line is to show that the variables can be accessed
因為我們破壞了根實例,所以將返回mainloop()
函數,這意味着它下面的任何代碼都將運行。 只要用戶界面處於打開狀態,它下面的代碼就不會運行。 因此,當關閉根窗口時,將運行其下面的代碼,並保存兩個變量供以后使用。 您應該在其中注釋掉一些錯誤檢查代碼。
我個人不使用.grid()
因為它可能會造成一些混亂。 相反,我喜歡使用.pack()
和封裝。 如果您想改用
.pack()
,這是另一個__init__
,它的工作原理相同。 我還使__init__
上的GUI看起來不太標准,並帶有一些TacoBell顏色:)
def __init__(self, root):
self.root = root
self.root.title("TacoBell TLD Tool")
self.root.geometry('600x300')
font20 = 'Calibri 20'
bfont20 = font20 + ' bold'
Label(self.root, text='TacoBell TLD Tool', font=bfont20, fg='purple').pack()
topItems = Frame(self.root)
Label(topItems, text="Store Number (XXXXXX): ", font=font20).pack(side=LEFT) # Sticky align text North(N), East(E), South(S), West(W)
self.entStore = Entry(topItems, font=font20)
self.entStore.pack(side=RIGHT)
topItems.pack(pady=20)
lowItems = Frame(self.root)
Label(lowItems, text="TLD Date(MM/DD/YYYY): ", font=font20).pack(side=LEFT)
self.entDate = Entry(lowItems, font=font20)
self.entDate.pack(side=RIGHT)
lowItems.pack(pady=20)
self.confirm = Button(root, text="Confirm", bg='purple', fg='white', font=bfont20, width=30, command=self.save)
self.confirm.pack()
最好的方法是使用組件。 使用tkinter,您應該通過擴展Frame
類來定義組件。 因此,您的代碼應如下所示:
class StoreForm(tkinter.Frame):
store_number = ''
tld_date = ''
def __init__(self, root, **kw):
super().__init__(**kw)
root.title("TacoBell TLD Tool")
self.store_number = tkinter.IntVar()
self.tld_date = tkinter.IntVar()
self.lblstore_number = tkinter.Label(self, text="Store Number (XXXXXX): ")
self.lbltld_date = tkinter.Label(self, text="TLD Date(MM/DD/YYYY): ")
self.lblstore_number.grid(row=0, sticky=E) # Sticky align text North(N), East(E), South(S), West(W0
self.lbltld_date.grid(row=1, sticky=E)
self.entStore = tkinter.Entry(self, textvariable=self.store_number)
self.entDate = tkinter.Entry(self, textvariable=self.tld_date)
self.entStore.grid(row=0, column=1)
self.entDate.grid(row=1, column=1)
注意, root
參數不是您的root,而是此框架的預期容器。
這樣,您就有了一個獨立的可重用圖形組件。 該組件管理視圖邏輯(顯示窗口小部件,如果需要,它們之間的交互),但不管理應用程序邏輯,這是控制器的工作。 但是要使用該控制器,您應該能夠從該組件獲取數據和/或提供一些數據。 為此,您應該添加方法。 即使使用相似的名稱,我也不會稱它們為getter和setter。
def get_data(self):
return self.store_number.get(), self.tld_date.get()
def set_data(self, store_number_value, tld_date_value):
self.store_number.set(store_number_value)
self.tld_date.set(tld_date_value)
現在,在您的主模塊中,您可以添加類似
MAIN_UI = tkinter.Tk()
form = StoreForm(MAIN_UI).pack()
我讓您選擇是否應該在模塊的根目錄或類內部進行。 這就是控制器應該在的地方。 控制器是您的業務邏輯在圖形組件之外的組件。
使用框架可讓您:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.