2016-12-07 2 views
1

포럼에 최근에 @Clueless_captain의 질문이 게시되었습니다. 그것은 @furas에 의해 응답되었습니다. 나는 그 대화에서 언급 할 수 없기 때문에 stackoverflow를 처음 사용한다. 이 대화의 URL은 (Tkinter Entry widget stays empty in larger programs (Python 2))입니다. furas가 게시 한 코드는 정확하게 내가하려고하는 것이 아니지만 자신이 할 수없는 유일한 것은 EntryWidget에 제공된 입력을 다시 사용할 수있는 방법을 찾는 것입니다. 나는 furas에 의해 작성된 코드를 수정했습니다. 내 목표는 GUI가 종료되기 전에 입력이 인쇄된다는 것입니다. 이를 위해 Return 키를 새로운 Function으로 바인딩했습니다.이 Function은이 새로운 Function에서 Textstring을 가져와 더 처리해야합니다. 두 번째 이름을 얻기 위해 버튼을 클릭 할 때만 수행됩니다. 본 윤리 강령의 명령이 해제 되었습니까? 문제가 10 번 줄에있는 문자열 'e.bind'과 밀접한 관련이 있다고 생각하지만 문제를 찾을 수 없습니다.TKinter : TopLevel()의 Entry-Widget에서 입력 재사용


최고 감사합니다, G_Lehmann

---------- 수정 된 코드 :


from Tkinter import * 

def get_input(text, variable): 
    win = Toplevel() 
    win.title("Get value") 

    f = LabelFrame(win, text=text) 
    f.pack() 

    e = Entry(win, textvariable=variable) 
    e.bind("<Return>", do_more(text, variable, e)) 
    e.pack(side="right") 
    #I tried e.bind here, but This had no Effect. 

    b = Button(win, text = "Cancel", command=win.destroy) 
    b.pack() 
#do_more is the new Function I want to use to process the Variable 'data' further. 
def do_more(text, variable, e): 
    data = e.get() 
    print data 
    print len(data) 
    print type(data) 

def get_value(text, variable): 
    get_input(text, variable) 

# --- main -- 

root = Tk() 
root.title("Ask-name-SUB") 

# global variables 
var_name = StringVar() 
var_address = StringVar() 

b = Button(root, text="Enter your name", command=lambda: get_value("Your name:", var_name)) 
b.pack() 

b = Button(root, text="Enter your address", command=lambda: get_value("Your address:", var_address)) 
b.pack() 

b = Button(root, text="Cancel", command=root.destroy) 
b.pack() 

root.mainloop() 

# --- after -- (My Edit: I disabled this as I want to bind the Variables before my GUI gets terminated) 
""" 
name = var_name.get() 
print "Print name, its length, its type" 
print name, len(name), type(name) 

address = var_address.get() 
print "Print address, its length, its type" 
print address, len(address), type(address) 
""" 
+0

귀하의 질문에 약간의 불확실성이 있습니다. 당신이 해결하려고하는 진짜 문제는 무엇입니까? 사용자에게 문자열을 입력하도록 요청하는 기능을 호출 할 수 있어야하며 해당 기능을 구성 가능하게하려고합니다 (예 : "성명"또는 "주소")? 또한, 정보를 출력하는 것이 진정한 목표입니까, 아니면 단지 설명을 목적으로'mainloop '이후의 인쇄문입니까? 대부분의 GUI는'mainloop '뒤에 어떤 코드도 없어야합니다. –

+0

'bind' ('command ='와 유사)는 함수 이름을 필요로합니다 - 그것은'()'와 인자가 없다는 것을 의미합니다. 'lambda'를 사용하여 함수를 'e.bind ("", lambda : do_more (text, variable, e))' – furas

+0

에 할당 할 수 있습니다. BTW : 두 번째 버튼을 만들 수 있습니다. ''OK ''-이 버튼에 기능을 지정하고 창을 닫기 전에 뭔가를하십시오. – furas

답변

0

bind이 (command=처럼) 함수 이름을 기대하고 그래서 당신은 인수를 사용하여 함수를 할당하려면 lambda을 사용해야합니다. 게다가 인수를 가진 bind execute 함수는 event이므로 수신해야합니다.

e.bind("<Return>", lambda event:do_more(variable)) 

당신은 버튼을 너무

b = Button(win, text="OK", command=lambda:do_more(variable)) 

do_more을 할당 할 수 있으며, ReturnButton와 동일한 작업을 수행 - 창 닫기 후 변수 뭔가.

창을 닫은 후에도 get_value에서 동일한 작업을 수행 할 수 있지만 일반적으로 tkinter는 창을 생성하고 닫을 때까지 기다리지 않으므로 win.wait_window()을 사용해야합니다.

그럼 이제 가치있는 것을 할 가능성이 두 가지 있습니다. do_more 또는 get_value 중 하나를 선택하십시오. 두 가지 방법 모두 수정이 가능합니다. 당신은 클래스를 사용하고 자신의 대화 상자 창을 만들 수 있습니다.

from Tkinter import * 

# --- --- 

# global variable to use in different functions 
win = None 

def get_input(text, variable): 
    global win # inform function to use global variable `win` to assign value 

    win = Toplevel() 
    win.title("Get value") 

    f = LabelFrame(win, text=text) 
    f.pack() 

    # use `f` instead of `win` to put inside LabelFrame 
    e = Entry(f, textvariable=variable) 
    e.pack()#side="right") 

    e.bind("<Return>", lambda event:do_more(variable)) 

    b = Button(win, text="OK", command=lambda:do_more(variable)) 
    b.pack() 

def do_more(variable): 
    data = variable.get() 
    print 'do_more:', data, len(data), type(data) 
    win.destroy() 

# --- --- 

def get_value(text, variable): 
    # create window 
    get_input(text, variable) 

    # this code is executed directly after creating window, not after closing window 
    # so code has to wait till window is closed 
    win.wait_window() 

    data = variable.get() 
    print 'get_value:', data, len(data), type(data) 

# --- main -- 

root = Tk() 
root.title("Ask-name-SUB") 

# global variables 
var_name = StringVar() 
var_address = StringVar() 

b = Button(root, text="Enter your name", command=lambda:get_value("Your name:", var_name)) 
b.pack() 

b = Button(root, text="Enter your address", command=lambda:get_value("Your address:", var_address)) 
b.pack() 

b = Button(root, text="Cancel", command=root.destroy) 
b.pack() 

root.mainloop() 
+0

제가 사용한 print 문구는 일러스트레이션을위한 것입니다. 진짜 프로그램은 9yearolds를위한 Textgame이 될 것입니다, 아마도 Annagrams에 관한 것입니다 (The Kids는 여전히 그들의 Class Project 이상으로 생각하고 있습니다). 그건 쉬운 부분이고 이미 파이썬을 배웠습니다. 하지만 나는 인터페이스를 구축 한 적이 없으며 그때는 더 많은 시간을 필요로합니다. 나는 당신의 코드를 시도했으며 정확히 내가하고 싶은 것입니다. 시간과 설명에 감사드립니다. G_Lehmann 최고 감사합니다. –