2017-05-04 11 views
0

テキスト入力フィールドが中央にあり、ユーザーの入力を返すカスタムテキスト入力ボックスを作成しようとしています。私は特に、他のプログラムでインポートして再利用できるものを作ることを試みています。私の現在の反復では、それが自分の.pyファイルに入っているときに入力を取得するためにうまく動作する "inputdialog"クラスを使用しますが、モジュールを別のスクリプトにインポートしようとすると "ok"ボタンは一見何もせず、 "x "ボタンがポップアップを閉じた後、" ImportError:名前をインポートできません "というエラーが表示されます。Python Tkinterのカスタムmsgboxがインポート中に失敗する

次のスタンドアロンスクリプトとして実行した場合、現在動作します私のコードです:

if __name__ == "__main__": 
    # These two lines below are needed to make sure that "askopenfilename" 
    # doesn't show it's top level tkinter window 
    root = Tk() 
    root.withdraw() 
    entdbemp = askopenfilename(title="Please select a file: ") 

    # Here is my non-working module call 
    master = inputdialog() 
    print(master.value) 

from tkinter import * 

class inputdialog: 
    def __init__(self): 
     self.value = None 
     self.root = Tk() 
     self.root.withdraw() 
     self.top = Toplevel(self.root) 


     Label(self.top, text="Value").pack() 
     self.e = Entry(self.top) 
     self.e.pack(padx=5) 

     b = Button(self.top, text="OK", command=self.ok) 
     b.pack(pady=5, padx=5, side="right") 
     self.root.mainloop() 

    def ok(self): 
     self.value = self.e.get() 
     self.root.destroy() 

if __name__ == "__main__": 
    test = inputdialog() 
    print(test.value) 

次は、私が現在動作していない別のプログラムの中にこのモジュールをインポートした方法です

インポート時に「OK」ボタンが機能しなくなるのはなぜですか?インポートするためにコードを修正できる方法はありますか? tkinterを使用してインポート可能なテキスト入力モジュールを作成するより良い方法がありますか?

+0

1つの問題は、 'Tk'の2つのインスタンスを作成していることです。 Tkinterは 'Tk'のインスタンスを1つだけ持つように設計されています。 –

答えて

2

問題はインポートとは関係ありません。問題は、2番目の例ではTk()を2回(各ファイルに1回)呼び出すことです。また、 'destroy'を呼び出すと、画面からGUIを削除するだけで、メインループを終了することはありません。

inputdialogクラスでルートを作成する行を削除し、mainloop()呼び出しをクラスの開始後にポイントに移動し、ウィンドウ):

from tkinter import * 
class inputdialog: 
    def __init__(self, master=None): 
     self.value = None 
     self.top = Toplevel(master) 

     Label(self.top, text="Value").pack() 
     self.e = Entry(self.top) 
     self.e.pack(padx=5) 

     b = Button(self.top, text="OK", command=self.ok) 
     b.pack(pady=5, padx=5, side="right") 

    def ok(self): 
     self.value = self.e.get() 
     self.top.quit() 

if __name__ == "__main__": 
    root = Tk() 
    root.withdraw() 
    master = inputdialog(root) 
    root.mainloop() 
    print(master.value) 

あなたがきちんとして適切になりたい場合は:また

import tkinter as tk 

class inputdialog(tk.Toplevel): 
    def __init__(self, master=None): 
     tk.Toplevel.__init__(self, master) 

     self.value = None 

     tk.Label(self, text="Value").pack() 
     self.e = tk.Entry(self) 
     self.e.pack(padx=5) 

     b = tk.Button(self, text="OK", command=self.ok) 
     b.pack(pady=5, padx=5, side="right") 

    def ok(self): 
     self.value = self.e.get() 
     self.quit() 

if __name__ == "__main__": 
    root = tk.Tk() 
    root.withdraw() 
    master = inputdialog(root) 
    root.mainloop() 
    print(master.value) 

:我々はサブクラスを作るのが好きではなくOOPとGUIで別のクラスをラップするクラスを、作るよりも、 、ワイルドカードのインポート(from module import *)はPEP8に対して醜いです。それらを使用しないでください。

ご参考までに、easyguiパッケージではすでにこれが行われています。それをインストールして使用したいだけかもしれません。

+0

ありがとう!私は家に帰るときにこれを試してみる。私は大したことはしません、将来的にはサブクラスを作ることを忘れないでください。ダブルTk()が問題になるかもしれないと思ったが、それを緩和する方法がわからなかった。ワイルドカードのインポートに関しては、私は急いで例を挙げてベースコードをつかんでいませんでした。(ごめんなさい!) – TheEmpireNeverEnded

+0

Hey @Novel、上記のコードをコピーしても同じ問題は解決しますが、私のPCとそれは正常に働いた。非常に奇妙な。私はそれが働くように思われるので、これを答えたものとしてマークします。私はちょうど私の環境に何か悪いと思う。 – TheEmpireNeverEnded

関連する問題