2016-08-11 8 views
0

저는 파이썬의 tkinter 모듈에 익숙하지 않으므로 모든 도움에 감사 드리며 이유가 무엇인지에 대한 설명도 있습니다.lambda 명령을 사용할 때 Python tkinter NameError

다음과 같은 형태의 4 튜플 목록이 있습니다. (foo, bar, x, y); 이런 일 : 적 기능을 갖는 각각의 버튼, 텍스트 bar와 버튼으로 가변 foo 인스턴스화

TUPLE_LIST = [('Hello', 'World', 0, 0), 
        ('Hovercraft', 'Eels', 50, 100), 
        etc.] 

나중에 for 루프 그리고, 행 각각 bar 이미 정의 된 그 장소 Entry 위젯을 추가 공동 좌표 x, y에서 그것을 :

for foo, bar, x, y in TUPLE_LIST: 
     exec("{0} = Button(self, text='{1}', command=lambda: self.update_text('{1}'))".format(foo, bar)) 
     eval(name).place(x=x, y=y) 

버튼 장소 완벽하지만, 내가받을 다음과 같은 오류 발생 중 하나를 클릭로 이동하는 경우 :

 Traceback (most recent call last): 
     File "...\lib\tkinter\__init__.py", line 1550, in __call__ 
     return self.func(*args) 
     File "<string>", line 1, in <lambda> 
    NameError: name 'self' is not defined 

나는 명령이 람다 (lambda)로 정의되어 있고 정의 된 '함수'가 아니라는 것을 짐작할 수있다. 그러나 나는 다른 사람들이 자신의 버튼을 정의하는 것을 보았다. 람다와 명령. 그래서 exec도 사용하는 것과 관련이 있습니까? (이 중요한 경우) 또한, 여기 update_text에 대한 코드는 다음과 같습니다

def update_text(self, new_char): 
     old_str = self.text_box_str.get() 
     # Above is a StringVar() defined in __init__ and used as textvariable in Entry widget creation. 
     self.text_box_str.set(old_str + new_char) 

어떤 도움이 많이 주시면 감사하겠습니다. 미리 감사드립니다.

답변

1

이것은 매우 나쁜 생각입니다. 변수 이름을 동적으로 작성하기 위해 건조하지 않아도됩니다. 코드가 복잡 해지고 관리하기가 어려워지고 읽기가 더 어려워집니다.

당신이 이름으로 위젯을 참조 할 경우

는, 사전 사용 : self의 문제에 관해서는

buttons = {} 
for foo, bar, x, y in TUPLE_LIST: 
    buttons[foo] = Button(self, text=bar, ...) 
    buttons[foo].place(...) 

을, 문제가 무엇인지 말할 수있는 충분한 코드가 아니다. 클래스를 사용하는 경우 코드는 괜찮아 보입니다. 그렇지 않은 경우 self을 사용하지 않아야합니다.

위젯을 업데이트하는 함수를 만들려면 해당 위젯이나 위젯의 이름을 함수에 전달하면됩니다. 어떤 위젯을 업데이트하고 싶은지 확실하지 않습니다. 그것은 엔트리 위젯 인 것 같습니다. 모든 버튼이 업데이트해야하는 엔트리 위젯 하나 또는 버튼 당 하나의 항목이 있는지는 알 수 없습니다. 나는 전자를 추측 할 것이다.

다음 예제에서는 추가 할 텍스트와 함께 변수를 변경하는 함수를 전달하는 방법을 보여줍니다. 이 솔루션은 textvariable 속성을 사용하지 않지만 원하는 경우 사용할 수 있습니다. 그냥 위젯보다는 그것을 전달하십시오. 물론

buttons[foo] = Button(..., command=lambda widget=self.text_box, value=bar: self.update_text(widget, value)) 
... 
def update_text(self, widget, value): 
    old_value = widget.get() 
    new_value = old_value + value 
    widget.delete(0, "end") 
    widget.insert(0, new_value) 

, 당신이하고있는 모든 문자열을 추가하는 경우, 당신은 충분히 공정, widget.insert("end", value)

+0

확인과 그 4 개 라인을 대체 할 수 있지만, 여전히 원래의 문제가 해결되지 않습니다. 그런 다음 어떻게 각각의 버튼이'Entry' 위젯에 자신의'bar '를 추가하는'command'를 갖도록 그런 방식으로 버튼을 만들까요? 왜냐하면 나는'exec' 호출에서 문자열 형식화 이외의 다른 방법을 생각할 수 없기 때문에 문제를 일으키는 것으로 보입니다. 그리고 예, 저는 수업을 사용하고 있습니다 (그러나 문제를 일으키는 '자아'는 나의 것조차도 아닙니다.). – ENPM

+0

@ENPM : 생성 된 문자열에'exec'를 호출하는 것이 사실상 불가능합니다.함수를 호출하고 업데이트 할 위젯을 전달하는 방법을 보여주기 위해 내 대답을 업데이트했습니다. 이 함수는 위젯 이름을 알 필요가 없으며 위젯 자체에 대한 참조를 제공 할 수 있습니다. –

+0

좋습니다, 감사합니다! 대신 그걸 줄께. – ENPM

관련 문제