Python Tkinter Spinboxes return 使用 for 循环的值

Python Tkinter Spinboxes return value using for loops

我正在尝试使用 X 多个旋转框,因为列表中有项目 - 所以使用 for 循环将它们放在屏幕上。

但是,当我单击按钮时,我似乎无法让它们达到 return 它们的值。

aStarter = ["Starter 1", "Starter 2", "Starter 3"]

def getOrders():
            aStarterOrder = []
            aMainOrder = []
            aDessertOrder = []
            for i in aStarterQuantity:
                aStarterOrder.append(StarterQuantity.get())

            print(aStarterOrder)

aStarterQuantity = []
        StarterQuantity = IntVar()
        for i in range(len(aStarter)):
            lbl = Label(self, text = aStarter[i]).grid(column = 0, row = 2 + i)
            StarterQuantity = Spinbox(self, from_=0, to=20, width=5, command=callback, font=Font(family='Helvetica', size=20, weight='bold')).grid(column = 1, row = 2 + i)
            print(StarterQuantity.get())

我尝试将 StarterQuantity 附加到 for 循环内的数组:

aStarterQuantity = []
        StarterQuantity = IntVar()
        for i in range(len(aStarter)):
            lbl = Label(self, text = aStarter[i]).grid(column = 0, row = 2 + i)
            StarterQuantity = Spinbox(self, from_=0, to=20, width=5, command=callback, font=Font(family='Helvetica', size=20, weight='bold')).grid(column = 1, row = 2 + i)
            aStarterQuantity.append(StarterQuantity.get())

这 return 是一个 None 类型错误 - 我似乎无法从旋转框中获取值。

有什么想法吗?

这是完整的代码(这是一个非常早期的 WIP!)

from tkinter import *
from tkinter.font import Font
import sqlite3
DatabaseFile = 'RMS.db'
connDatabase = sqlite3.connect(DatabaseFile)

#Creating a cursor to run SQL Commands
DatabaseSelect = connDatabase.cursor()

#Selecting all Menu Data
DatabaseSelect.execute("SELECT * FROM MENU")
MenuData = DatabaseSelect.fetchall()


class Main(Tk): #This sets up the initial Frame in a Window called Main
    def __init__(self): #This creates a controller to use the Frames
        Tk.__init__(self) #This creates a Window within the controller
        self._frame = None #This sets the frame to have a value of None - this makes sure the main Window doesn't get destroyed by the switch frame function
        self.switch_frame(Home)

    def switch_frame(self, frame_class): #This function is used to switch frames. Self is the master frame, frame_class is the name of the Class (page) being passed int
        new_frame = frame_class(self)
        if self._frame is not None:
            self._frame.destroy() #Destroy any frames except the master
        self._frame = new_frame #Make a new frame
        self._frame.grid(column=0, row=0) #Put the frame in the top left

class Home(Frame):
    def __init__(self, master):
        Frame.__init__(self, master)
        Label(self, text="The White Horse").grid(column = 0, row = 0)
        btnPage1 = Button(self, text="Orders", command=lambda: master.switch_frame(Orders)).grid(column = 1, row = 0)


#Making a blank page with a return home button
class Orders(Frame): #This sets up a class called Page1 - Each new page will need a new class.
    def __init__(self, master): #This sets up a controller to put things into the Frame
        Frame.__init__(self, master) #Make the frame using the controller

        #Get list of Starters from Menu Data
        aStarter = ["Starter 1", "Starter 2", "Starter 3"]
        aMain = []
        aDessert = []
        for i in MenuData:
            if i[3] == "Starters":
                aStarter.append(i[1])
            if i[3] == "Main":
                aMain.append(i[1])
            if i[3] == "Dessert":
                aDessert.append(i[1])
        def getOrders():
            aStarterOrder = []
            aMainOrder = []
            aDessertOrder = []
            for i in aStarterQuantity:
                aStarterOrder.append(StarterQuantity.get())

            print(aStarterOrder)

        def callback():
            print(StarterQuantity.get())
            
                
        #Starter Section
        boxes = []
        aStarterQuantity = []
        StarterQuantity = IntVar()
        for i in range(len(aStarter)):
            lbl = Label(self, text = aStarter[i]).grid(column = 0, row = 2 + i)
            StarterQuantity = Spinbox(self, from_=0, to=20, width=5, command=callback, font=Font(family='Helvetica', size=20, weight='bold')).grid(column = 1, row = 2 + i)
            aStarterQuantity.append(StarterQuantity.get())
            
      
        #Mains Sections
        for i in range(len(aMain)):
            lbl = Label(self, text = aMain[i]).grid(column = 6, row = 2 + i)
            MainQuantity = Spinbox(self, from_=0, to=20, width=5, font=Font(family='Helvetica', size=20, weight='bold')).grid(column = 7, row = 2 + i)

        #Dessert Section
        for i in range(len(aDessert)):
            lbl = Label(self, text = aDessert[i]).grid(column = 12, row = 2 + i)
            DessertQuantity = Spinbox(self, from_=0, to=20, width=5, font=Font(family='Helvetica', size=20, weight='bold')).grid(column = 13, row = 2 + i)
        
        btnHome = Button(self, text="Home", command=lambda: master.switch_frame(Home)).grid(column = 0, row = 1) #Add a Button
        btnSubmitEntries = Button(self, text = "Submit", command = getOrders).grid(column = 0, row= 20)

  
    

Main = Main()
Main.geometry("1200x800")
Main.mainloop()

问题似乎是 grid 方法没有 return 任何东西,所以 StarterQuantity 被分配 None 即默认 return 值对于一个函数。

for i in range(len(aStarter)):

    lbl = Label(self, text=aStarter[i])
    lbl.grid(column=0, row=2 + i)

    sq_font = Font(family='Helvetica', 
                   size=20,
                   weight='bold')
      
    StarterQuantity = Spinbox(self,
                              from_=0,
                              to=20,
                              width=5,                              command=callback, 
                              font=sq_font)
    StarterQuantity.grid(column=1, row=2 + i)

    aStarterQuantity.append(StarterQuantity.get())

这适用于我的情况。 (取出 SpinboxFont 参数以提高移动设备的可读性)。

不相关的注释;我不知道你 prefer/have 维护什么代码风格,当然这取决于你,但我认为提及 Python (PEP8) 中的命名风格约定可能会有所帮助class 名称使用 CamelCase,变量名称使用 lower_case_w_underscores,常量使用 functions/methods,SCREAMING_SNAKE。