动态定义tkinter GUI小部件(for循环)-最后一项胜出

时间:2018-11-27 20:35:47

标签: python linux python-3.x tkinter mint

我正在尝试使用Python3 / tkinter创建一个GUI,并且当我独立定义每个小部件时,行为均符合预期。当我尝试使用循环定义小部件时,GUI似乎只承认最后一次迭代。在工作示例中,您可以看到单击每个按钮两次,按钮会更改相应引脚对象的状态,但是在失败的带有循环的示例中,两个按钮似乎都作用于pin1(此示例中循​​环的最后一个引脚) )。我怀疑我使用的列表不正确,但这是我的第一个真正的python脚本,因此我不确定。

Working example - Screen shot

button[1] = Button(window1, textvariable=pins[1].statestr, command=lambda: pins[1].changeState('pin1'))
button[1].grid(row=rowG, column=0)
labels[1] = Label(window1, text='label1')
labels[1].grid(row=rowG, column=1) 
rowG += 1

button[2] = Button(window1, textvariable=pins[2].statestr, command=lambda: pins[2].changeState('pin2'))
button[2].grid(row=rowG, column=0)
labels[1] = Label(window1, text='label2')
labels[1].grid(row=rowG, column=1) 
rowG += 1

Failing Example - Screen shot

for i in range(num_pins):
    button[i] = Button(window1, textvariable=pins[i].statestr, command=lambda: pins[i].changeState('pin'+str(i)))
    button[i].grid(row=rowG, column=0)
    labels[i] = Label(window1, text='label'+str(i))
    labels[i].grid(row=rowG, column=1) 
    rowG += 1

我已经将整个程序剥离为一个正常的准系统示例,并将其包含在下面。

import tkinter as tk
from tkinter import *

class Pin(object):
    pintype = ""  # input output
    state = 0
    statestr = ""

    # The class "constructor" - It's actually an initializer 
    def __init__(self, pintype, state, name):
        self.pintype = pintype
        self.state = state
        self.statestr = StringVar()
        self.statestr.set("Off")
        print("Creating " + name + " - " + str(state))

    def changeState(self,name):
        print("\nChanging state of " + name + "...")
        print("  Old state was " + str(self.state))
        if self.state:
            self.state = 0
            self.statestr.set("Off")
        else:
            self.state = 1
            self.statestr.set("On")
        print("  New state is " + str(self.state))


def definePin(pintype, state, name):
    pin = Pin(pintype, state, name)
    return pin

## Define GUI
window1 = Tk()
num_pins = 2
pins = [definePin("output", 0, 'pin'+str(i)) for i in range(num_pins)]  #    create pin objects
button = [None] * num_pins                                              # create empty button list
labels = [None] * num_pins                                              # create empty labels list

window1.title("Raspberry Pi GUI")
rowG = 0

## Failing Loop
for i in range(num_pins):
    button[i] = Button(window1, textvariable=pins[i].statestr, command=lambda: pins[i].changeState('pin'+str(i)))
    button[i].grid(row=rowG, column=0)
    labels[i] = Label(window1, text='label'+str(i))
    labels[i].grid(row=rowG, column=1) 
    rowG += 1
## End Failing Loop

## Working code
#button[1] = Button(window1, textvariable=pins[1].statestr, command=lambda: pins[1].changeState('pin1'))
#button[1].grid(row=rowG, column=0)
#labels[1] = Label(window1, text='label1')
#labels[1].grid(row=rowG, column=1) 
#rowG += 1

#button[2] = Button(window1, textvariable=pins[2].statestr, command=lambda: pins[2].changeState('pin2'))
#button[2].grid(row=rowG, column=0)
#labels[1] = Label(window1, text='label2')
#labels[1].grid(row=rowG, column=1) 
#rowG += 1
## END Working code

close_button = Button(window1, text="Close", command=window1.quit)
close_button.grid(row=rowG, column=2, sticky=E)        

window1.mainloop()

我不知道这很重要,但是我正在Linux Mint机器上运行。

0 个答案:

没有答案