1

ゴール

ユーザーからエントリを取得して返す単純な機能を持つ他のすべてのプログラムにインポートできる基本的なファイルを作成しようとしています。

コード

そのために、次のコードがあります。

class takeInput(object):

    def __init__(self,requestMessage,parent):

        self.string = ''
        self.frame = Frame(parent)
        self.frame.pack()        
        self.acceptInput(requestMessage)

    def acceptInput(self,requestMessage):

        r = self.frame

        k = Label(r,text=requestMessage)
        k.pack(side='left')
        self.e = Entry(r,text='Name')
        self.e.pack(side='left')
        self.e.focus_set()
        b = Button(r,text='okay',command=self.gettext)
        b.pack(side='right')

    def gettext(self):
        self.string = self.e.get()
        self.frame.destroy()
        print self.string

    def getString(self):
        return self.string

def getText(requestMessage,parent):
    global a
    a = takeInput(requestMessage,parent)
    return a.getString()

また、これをテストするためにスクリプト レベルのコードを追加しました。

root = Tk()

getText('enter your name',root)

var = a.getString()

print var

root.mainloop()

そして、私を本当に困惑させているのは、次のことです。

  1. var入力した値がありません 空の文字列があります''
  2. a.string変数には入力した値があり、これをシェルから確認しました。

またa.getString()、から返された文字列をシェルに割り当てようとすると、varうまくいきました。

私はTkinterプログラミングに慣れていないため、その仕組みを完全には理解していませmainloop()。ですから、これが問題だったのかもしれません。しかし、よくわかりません。

仕様

OS:リナックスミント14

Python IDLE 2.7

この問題で私を助けてください。

4

4 に答える 4

12

他の回答が示すようvarに、メインループに入る前、つまりウィンドウが実際に実行される前に印刷し、プログラムはユーザーの入力を待っています。

tkSimpleDialogあなたの意見を得るために家族に頼ることができます:

import Tkinter
import tkSimpleDialog

root = Tkinter.Tk()
var = tkSimpleDialog.askstring("Name prompt", "enter your name")
print var

自分のやり方を追求したい場合は、「OK」ボタンのコールバック(gettextあなたの場合)から印刷を実行できます。「OK」が押されたときに仮想イベントを生成し、メイン プログラムでこのイベントにバインドすることもできます ( http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/virtual-events.html ) 。

于 2013-03-20T13:34:43.243 に答える
7

コードの流れは次のようになります。

  • メイン スコープは を呼び出しますgetText
  • getTexttakeInputオブジェクトを作成しますa
  • takeInputオブジェクトは自身を初期化し、ラベルやボタンなどを作成します。
  • getTextを返しますa.getString()。これはself.string、まだデフォルト値である空の文字列を持っています。
  • メインスコープvarは空であるを出力します。

これまでのところ、これらすべてが数ナノ秒以内に行われています。ユーザーはまだウィンドウを見たことさえありません。

次に、メイン スコープが を呼び出しroot.mainloop()、最終的にユーザーにウィンドウを操作する機会を与えます。しかし、手遅れです。varすでに印刷されています。

getTextユーザーがテキストを送信するまで戻りたくない場合は、その後でmainloopはなく、内部getTextで発生する必要があります。

from Tkinter import *

class takeInput(object):

    def __init__(self,requestMessage):
        self.root = Tk()
        self.string = ''
        self.frame = Frame(self.root)
        self.frame.pack()        
        self.acceptInput(requestMessage)

    def acceptInput(self,requestMessage):
        r = self.frame

        k = Label(r,text=requestMessage)
        k.pack(side='left')
        self.e = Entry(r,text='Name')
        self.e.pack(side='left')
        self.e.focus_set()
        b = Button(r,text='okay',command=self.gettext)
        b.pack(side='right')

    def gettext(self):
        self.string = self.e.get()
        self.root.destroy()

    def getString(self):
        return self.string

    def waitForInput(self):
        self.root.mainloop()

def getText(requestMessage):
    msgBox = takeInput(requestMessage)
    #loop until the user makes a decision and the window is destroyed
    msgBox.waitForInput()
    return msgBox.getString()

var = getText('enter your name')
print "Var:", var
于 2013-03-20T12:23:00.803 に答える
1

var問題は、テキストが入力されるどころか、ダイアログが表示される前に、テスト ルーチンが既に の値を出力していることです。(これは、テスト コードにいくつかのステートメントを追加することで簡単に検証できprintます。) これは、 への呼び出しがmainloop()最後にあるためです。代わりに、フレームを作成した後、入力を読み取って返す前に呼び出す必要がmainloop あります。たとえば、getTextメソッドに移動する場合があります。

def getText(requestMessage,parent):
    a = takeInput(requestMessage,parent)
    parent.mainloop()
    return a.getString()

[x]「OK」をクリックした後でもダイアログを閉じる(-ボタンをクリックする)必要があるため、これはまだうまく機能しません。これを修正する方法がわかりません。

ただし、このためのモジュール既に存在することに注意してください。このような入力ダイアログを表示tkSimpleDialogするなどのメソッドを提供します。askstring(title, prompt)そのため、それらを使用するか、ソース コード (で見つかる/usr/lib/python2.7/lib-tkなど) を見て、それがどのように行われているかを調べることができます。

于 2013-03-20T12:27:29.673 に答える