Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PythonTkinter,按钮列表_Python_List_Button_Tkinter - Fatal编程技术网

PythonTkinter,按钮列表

PythonTkinter,按钮列表,python,list,button,tkinter,Python,List,Button,Tkinter,我在将按钮对象放入列表时遇到了一个问题。 我不确定我想实现的目标是否真的能实现,但事实就是如此 工作样本: from tkinter import * class Main(Frame): def __init__(self, master = None): Frame.__init__(self, master) self.pack(fill = 'both', expand = True) # General purpose var

我在将按钮对象放入列表时遇到了一个问题。
我不确定我想实现的目标是否真的能实现,但事实就是如此

工作样本:

from tkinter import *

class Main(Frame):
    def __init__(self, master = None):
        Frame.__init__(self, master)
        self.pack(fill = 'both', expand = True)

        # General purpose variables     ----------
        self.isButtonSelected = False

        self.isButton_A_Selected = False    # controll boolean
        self.isButton_B_Selected = False
        self.isButton_C_Selected = False
        self.isButton_D_Selected = False

        # Layers                        ----------
        self.background = Frame(self)

        # Buttons                       ----------
        self.button_A = Button(self.background, text = "A", bg = 'white', command = self.selectButton_A)
        self.button_B = Button(self.background, text = "B", bg = 'white', command = self.selectButton_B)
        self.button_C = Button(self.background, text = "C", bg = 'white', command = self.selectButton_C)
        self.button_D = Button(self.background, text = "D", bg = 'white', command = self.selectButton_D)

        # Packs                         ----------
        #layers
        self.background.pack(fill = 'both', expand = True)
        #buttons
        btnPackPrefix = {'side' : 'left', 'fill' : 'both', 'expand' : 'True'}
        self.button_A.pack(btnPackPrefix)
        self.button_B.pack(btnPackPrefix)
        self.button_C.pack(btnPackPrefix)
        self.button_D.pack(btnPackPrefix)

    def selectButton_A(self):
        '''The idea here is similar to radiobuttons.
           Click to select. Click same to deselect.
           Click other to deselect old and select new.
           Only one button can be selected at a time.
               -repeated for all similar methods.'''

        if self.isButtonSelected == False:          # click-select
            self.button_A.config(bg = 'green')
            self.isButtonSelected = True
            self.isButton_A_Selected = True
        else:                                       
            if self.isButton_A_Selected:                # click-deselect
                self.resetButtons()
                self.isButtonSelected = False
            else:                                       # deselect other and select this
                self.resetButtons()
                self.button_A.config(bg = 'green')
                self.isButtonSelected = True
                self.isButton_A_Selected = True

    def selectButton_B(self):
        if self.isButtonSelected == False:
            self.button_B.config(bg = 'green')
            self.isButtonSelected = True
            self.isButton_B_Selected = True
        else:
            if self.isButton_B_Selected:
                self.resetButtons()
                self.isButtonSelected = False
            else:
                self.resetButtons()
                self.button_B.config(bg = 'green')
                self.isButtonSelected = True
                self.isButton_B_Selected = True

    def selectButton_C(self):
        if self.isButtonSelected == False:
            self.button_C.config(bg = 'green')
            self.isButtonSelected = True
            self.isButton_C_Selected = True
        else:
            if self.isButton_C_Selected:
                self.resetButtons()
                self.isButtonSelected = False
            else:
                self.resetButtons()
                self.button_C.config(bg = 'green')
                self.isButtonSelected = True
                self.isButton_C_Selected = True

    def selectButton_D(self):
        if self.isButtonSelected == False:
            self.button_D.config(bg = 'green')
            self.isButtonSelected = True
            self.isButton_D_Selected = True
        else:
            if self.isButton_D_Selected:
                self.resetButtons()
                self.isButtonSelected = False
            else:
                self.resetButtons()
                self.button_D.config(bg = 'green')
                self.isButtonSelected = True
                self.isButton_D_Selected = True

    def resetButtons(self):
        '''this pretty much resets all buttons and controll booleans
           to their default state'''
        #A
        self.button_A.config(bg = 'white')  # paint button white
        self.isButton_A_Selected = False    # controll boolean reset
        #B
        self.button_B.config(bg = 'white')
        self.isButton_B_Selected = False
        #C
        self.button_C.config(bg = 'white')
        self.isButton_C_Selected = False
        #D
        self.button_D.config(bg = 'white')
        self.isButton_D_Selected = False


def run_Application():
    app = Main()
    app.master.geometry('200x50')
    app.mainloop()

run_Application()
from tkinter import *

class Main(Frame):
    def __init__(self, master = None):
        Frame.__init__(self, master)
        self.pack(fill = 'both', expand = True)

        # General purpose variables     ----------
        self.isButtonSelected = False

        self.isButton_A_Selected = False    # controll boolean
        self.isButton_B_Selected = False
        self.isButton_C_Selected = False
        self.isButton_D_Selected = False

        # Layers                        ----------
        self.background = Frame(self)

        # Buttons                       ----------
        self.button_A = Button(self.background, text = "A", bg = 'white', command = self.selectButton(0)) # apparently this doesn't work...
        self.button_B = Button(self.background, text = "B", bg = 'white', command = self.selectButton(1))
        self.button_C = Button(self.background, text = "C", bg = 'white', command = self.selectButton(2))
        self.button_D = Button(self.background, text = "D", bg = 'white', command = self.selectButton(3))

        # Packs                         ----------
        #layers
        self.background.pack(fill = 'both', expand = True)
        #buttons
        btnPackPrefix = {'side' : 'left', 'fill' : 'both', 'expand' : 'True'}
        self.button_A.pack(btnPackPrefix)
        self.button_B.pack(btnPackPrefix)
        self.button_C.pack(btnPackPrefix)
        self.button_D.pack(btnPackPrefix)

    def selectButton(self, i = None):
        '''The idea here is similar to radiobuttons.
           Click to select. Click same to deselect.
           Click other to deselect old and select new.
           Only one button can be selected at a time.
               -do that only on objects
                 at [i]. 'i' is given from the button command'''

        global buttons, btn_bools

        buttons = [self.button_A, self.button_B,
                   self.button_C, self.button_D]    # list buttons.  # Raises error. It seems that Button objects cannot be listed

        btn_bools = [self.isButton_A_Selected, self.isButton_B_Selected,
                     self.isButton_C_Selected, self.isButton_D_Selected]    # list contoll booleans

        if self.isButtonSelected == False:          # click-select
            self.buttons[i].config(bg = 'green')
            self.isButtonSelected = True
            self.btn_bools[i] = True
        else:                                       
            if self.isButton_A_Selected:                # click-deselect
                self.resetButtons()
                self.isButtonSelected = False
            else:                                       # deselect other and select this
                self.resetButtons()
                self.buttons[i].config(bg = 'green')
                self.isButtonSelected = True
                self.btn_bools[i] = True

    def resetButtons(self):
        '''iterate through all buttons/controll booleans
           and reset to their default state'''

        for b in range(len(buttons)):
            buttons[b].config(bg = 'white')

        for bb in range(len(btn_bools)):
            btn_bools[bb] = False



def run_Application():
    app = Main()
    app.master.geometry('200x50')
    app.mainloop()

run_Application()
正如您所注意到的,我的代码有很多复制粘贴的代码片段,每个片段中的细节都发生了更改。
所以我得想办法把它缩短。。我需要一个控制所有这些操作的函数
因为它们是相似的

我想到了这个

非工作样本:

from tkinter import *

class Main(Frame):
    def __init__(self, master = None):
        Frame.__init__(self, master)
        self.pack(fill = 'both', expand = True)

        # General purpose variables     ----------
        self.isButtonSelected = False

        self.isButton_A_Selected = False    # controll boolean
        self.isButton_B_Selected = False
        self.isButton_C_Selected = False
        self.isButton_D_Selected = False

        # Layers                        ----------
        self.background = Frame(self)

        # Buttons                       ----------
        self.button_A = Button(self.background, text = "A", bg = 'white', command = self.selectButton_A)
        self.button_B = Button(self.background, text = "B", bg = 'white', command = self.selectButton_B)
        self.button_C = Button(self.background, text = "C", bg = 'white', command = self.selectButton_C)
        self.button_D = Button(self.background, text = "D", bg = 'white', command = self.selectButton_D)

        # Packs                         ----------
        #layers
        self.background.pack(fill = 'both', expand = True)
        #buttons
        btnPackPrefix = {'side' : 'left', 'fill' : 'both', 'expand' : 'True'}
        self.button_A.pack(btnPackPrefix)
        self.button_B.pack(btnPackPrefix)
        self.button_C.pack(btnPackPrefix)
        self.button_D.pack(btnPackPrefix)

    def selectButton_A(self):
        '''The idea here is similar to radiobuttons.
           Click to select. Click same to deselect.
           Click other to deselect old and select new.
           Only one button can be selected at a time.
               -repeated for all similar methods.'''

        if self.isButtonSelected == False:          # click-select
            self.button_A.config(bg = 'green')
            self.isButtonSelected = True
            self.isButton_A_Selected = True
        else:                                       
            if self.isButton_A_Selected:                # click-deselect
                self.resetButtons()
                self.isButtonSelected = False
            else:                                       # deselect other and select this
                self.resetButtons()
                self.button_A.config(bg = 'green')
                self.isButtonSelected = True
                self.isButton_A_Selected = True

    def selectButton_B(self):
        if self.isButtonSelected == False:
            self.button_B.config(bg = 'green')
            self.isButtonSelected = True
            self.isButton_B_Selected = True
        else:
            if self.isButton_B_Selected:
                self.resetButtons()
                self.isButtonSelected = False
            else:
                self.resetButtons()
                self.button_B.config(bg = 'green')
                self.isButtonSelected = True
                self.isButton_B_Selected = True

    def selectButton_C(self):
        if self.isButtonSelected == False:
            self.button_C.config(bg = 'green')
            self.isButtonSelected = True
            self.isButton_C_Selected = True
        else:
            if self.isButton_C_Selected:
                self.resetButtons()
                self.isButtonSelected = False
            else:
                self.resetButtons()
                self.button_C.config(bg = 'green')
                self.isButtonSelected = True
                self.isButton_C_Selected = True

    def selectButton_D(self):
        if self.isButtonSelected == False:
            self.button_D.config(bg = 'green')
            self.isButtonSelected = True
            self.isButton_D_Selected = True
        else:
            if self.isButton_D_Selected:
                self.resetButtons()
                self.isButtonSelected = False
            else:
                self.resetButtons()
                self.button_D.config(bg = 'green')
                self.isButtonSelected = True
                self.isButton_D_Selected = True

    def resetButtons(self):
        '''this pretty much resets all buttons and controll booleans
           to their default state'''
        #A
        self.button_A.config(bg = 'white')  # paint button white
        self.isButton_A_Selected = False    # controll boolean reset
        #B
        self.button_B.config(bg = 'white')
        self.isButton_B_Selected = False
        #C
        self.button_C.config(bg = 'white')
        self.isButton_C_Selected = False
        #D
        self.button_D.config(bg = 'white')
        self.isButton_D_Selected = False


def run_Application():
    app = Main()
    app.master.geometry('200x50')
    app.mainloop()

run_Application()
from tkinter import *

class Main(Frame):
    def __init__(self, master = None):
        Frame.__init__(self, master)
        self.pack(fill = 'both', expand = True)

        # General purpose variables     ----------
        self.isButtonSelected = False

        self.isButton_A_Selected = False    # controll boolean
        self.isButton_B_Selected = False
        self.isButton_C_Selected = False
        self.isButton_D_Selected = False

        # Layers                        ----------
        self.background = Frame(self)

        # Buttons                       ----------
        self.button_A = Button(self.background, text = "A", bg = 'white', command = self.selectButton(0)) # apparently this doesn't work...
        self.button_B = Button(self.background, text = "B", bg = 'white', command = self.selectButton(1))
        self.button_C = Button(self.background, text = "C", bg = 'white', command = self.selectButton(2))
        self.button_D = Button(self.background, text = "D", bg = 'white', command = self.selectButton(3))

        # Packs                         ----------
        #layers
        self.background.pack(fill = 'both', expand = True)
        #buttons
        btnPackPrefix = {'side' : 'left', 'fill' : 'both', 'expand' : 'True'}
        self.button_A.pack(btnPackPrefix)
        self.button_B.pack(btnPackPrefix)
        self.button_C.pack(btnPackPrefix)
        self.button_D.pack(btnPackPrefix)

    def selectButton(self, i = None):
        '''The idea here is similar to radiobuttons.
           Click to select. Click same to deselect.
           Click other to deselect old and select new.
           Only one button can be selected at a time.
               -do that only on objects
                 at [i]. 'i' is given from the button command'''

        global buttons, btn_bools

        buttons = [self.button_A, self.button_B,
                   self.button_C, self.button_D]    # list buttons.  # Raises error. It seems that Button objects cannot be listed

        btn_bools = [self.isButton_A_Selected, self.isButton_B_Selected,
                     self.isButton_C_Selected, self.isButton_D_Selected]    # list contoll booleans

        if self.isButtonSelected == False:          # click-select
            self.buttons[i].config(bg = 'green')
            self.isButtonSelected = True
            self.btn_bools[i] = True
        else:                                       
            if self.isButton_A_Selected:                # click-deselect
                self.resetButtons()
                self.isButtonSelected = False
            else:                                       # deselect other and select this
                self.resetButtons()
                self.buttons[i].config(bg = 'green')
                self.isButtonSelected = True
                self.btn_bools[i] = True

    def resetButtons(self):
        '''iterate through all buttons/controll booleans
           and reset to their default state'''

        for b in range(len(buttons)):
            buttons[b].config(bg = 'white')

        for bb in range(len(btn_bools)):
            btn_bools[bb] = False



def run_Application():
    app = Main()
    app.master.geometry('200x50')
    app.mainloop()

run_Application()
我尝试用包含Int属性和
它工作得很好

从错误报告中,我了解到,如果不是不可能的话,列出按钮也不是一个好主意

我在谷歌上搜索了很多例子或类似的问题,但我没有
得到任何好的结果

我还搜索了Python和
我弄糊涂了。我想看看是否可以保存一个指向
但我认为结果是一样的。。列表将其对象读取为按钮和
引起错误

因此,我的问题是:
1.这能做到吗?(显著缩短第一个代码示例。)
2.关于列出按钮或小部件的一般情况:如果可以,如何完成?如果没有,原因是什么?
3.在第二个代码示例中,我需要我的按钮命令来包含'i'参数
这是我的职能所需要的。这个怎么打?似乎仅仅添加(i)是不起作用的


提前谢谢

看看这行代码:

self.button_A = Button(..., command = self.selectButton(0)) 
发生了什么事?
self.selectButton(0)
做什么?您正在调用函数
self.selectButton(0)
,然后将该函数的结果用作
命令
属性的值。这几乎肯定不是你想要的

你需要做的是以下几点:

self.button_A = Button(..., command = lambda: self.selectButton(0))
这会推迟对
self.selectButton
的调用,直到实际单击该按钮。这将允许创建按钮,如果愿意,您可以将它们分配到列表中:

self.buttons = [self.button_A, self.button_B, self.button_C, self.button_D]

哦,我明白了。。所以问题是Python试图在定义按钮之前执行函数。我还没有用过lambdas,所以我想是时候开始阅读了!谢谢!它现在工作得很好!