2012-01-21 10 views
0

Ubuntu Linuxの11.04/Pythonの2.7/TkinterのはTkinterのが唯一のユニークなオブジェクト上の

仕事にpack_forgetましょう私は、PythonのGUIで初心者だと私はトラブル単一のオブジェクトが消え、再び現れる作りを抱えています。 pack_forgetは私のための仕事のようなものですが、私がやっているやり方では、一度に1つだけ必要なときに、すべてのオブジェクトを点滅させます。下の煮詰めた例では、オブジェクト "a"を表示して消してから、オブジェクト "b"に対して同じことをしようとしています。

私はどんなヘルプにも非常に感謝しています。また、これに関するいくつかの優れたドキュメントも素晴らしいです。私が見つけることができたものは、例の上で軽いものでした。

from Tkinter import * 
import time 

class Box: 
    def __init__(self, canvas): 
      self.canvas = canvas 
    def type(self, type): 
     if type == "1": 
      self.if = self.canvas.create_rectangle(0, 0, 50, 50, fill="red") 
     elif type == "2": 
      self.if = self.canvas.create_rectangle(50, 50, 100, 100, fill="blue") 
    def hide(self): 
     self.canvas.pack_forget() 
     self.canvas.update_idletasks() 
     root.update() 
    def unhide(self): 
     self.canvas.pack() 
     self.canvas.update_idletasks() 
     root.update() 

root = Tk() 
frame = Frame(root) 
frame.pack() 
canvas = Canvas(frame, width=500, height=200) 
canvas.pack() 
root.update() 

a = Box(canvas) 
a.type("1") 
b = Box(canvas) 
b.type("2") 

a.unhide() 
time.sleep(.5) 
a.hide() 
time.sleep(1) 

b.unhide() 
time.sleep(.5) 
b.hide() 
time.sleep(1) 

答えて

3

コードには多くの不具合があります。 1つは、イベントループを持つプログラムでsleepを決して呼び出すべきではありません。それを呼び出すと、プログラム全体がフリーズします。一定期間後に何かが起きるようにしたい場合は、afterメソッドを使用して、今後実行する機能のスケジュールを設定します。

第2に、self.canvas.update_idletasksを呼び出した後、root.updateを呼び出すことに意味がありません。 1つは、決してupdateと呼ぶべきではありません。あなたがそれを分かっているならばupdateに電話をかけても構いませんが、学習しているだけで知らないので、それを呼び出すのは安全ではないと想定します。プラスupdateupdate_idletasks以上と同じ働きをしますので、更新を呼び出すことを選択した場合は、update_idletasksを呼び出す必要はありません。

本当の問題です。 2つの別個の「ボックス」オブジェクトを作成したいと思っていて、それらを個別に非表示にして表示したいのですか?ただし、両方のボックスは、同じキャンバスに描画される矩形です。 pack_forgetに電話すると、キャンバス全体に影響を及ぼし、これらのオブジェクトが消えてから再び表示されます。

あなたの意図は明確ではありません。 "Box"の各インスタンスがキャンバス上の単なる矩形である場合、pack_forgetはキャンバスオブジェクトではなくウィジェットで機能するため、使用したくないです。

矩形を表示して消したい場合は、いくつかの選択肢があります。毎回破棄して再作成するか、またはキャンバスmoveまたはcoordsメソッドを使用してアイテムをキャンバスの非表示部分に移動できます。スタッキング命令を操作して、他のオブジェクトの上または下のオブジェクトを上下させることもできます。

ここでは、キャンバスの表示領域外にアイテムを移動するトリックを使用する簡単な例を示します。あなたが本当にしたいことは、オブジェクトが連続して点滅させるためであれば

from Tkinter import * 
import time 

class Box: 
    def __init__(self, canvas, type): 
     self.canvas = canvas 
     if type == "1": 
      self.rect = canvas.create_rectangle(0, 0, 50, 50, fill="red") 
     elif type == "2": 
      self.rect = canvas.create_rectangle(50, 50, 100, 100, fill="blue") 
     self.coords = canvas.coords(canvas, self.rect) 

    def hide(self): 
     # remember where this object was 
     self.coords = canvas.coords(self.rect) 
     # move it to an invisible part of the canvas 
     self.canvas.move(self.rect, -1000, -1000) 
    def unhide(self): 
     # restore it to where it was 
     self.canvas.coords(self.rect, *self.coords) 

root = Tk() 
frame = Frame(root) 
frame.pack() 
canvas = Canvas(frame, width=500, height=200) 
canvas.pack() 

a = Box(canvas, type="1") 
b = Box(canvas, type="2") 

root.after(1000, a.hide) 
root.after(2000, a.unhide) 
root.after(3000, b.hide) 
root.after(4000, b.unhide) 

root.mainloop() 

は最後に、あなたは自動的にhideメソッドを持ってunhide方法及びその逆呼び出すことができます。

def hide(self): 
     # remember where this object was 
     self.coords = canvas.coords(self.rect) 
     # move it to an invisible part of the canvas 
     self.canvas.move(self.rect, -1000, -1000) 
     # unhide after a second 
     self.canvas.after(1000, self.unhide) 

    def unhide(self): 
     # restore it to where it was 
     self.canvas.coords(self.rect, *self.coords) 
     # re-hide after a second 
     self.canvas.after(1000, self.hide) 
+0

グレートを!すべての提案は歓迎され、貪欲に取られました。 私はちょうど私自身の小さなプロジェクトでこれに私の歯を切っている。私の元のコードから 'update'を取り除くことは、実際に働いていた方法を打破することに注意してください。しかし、とにかく正しい方向に向かうようなものではありません。 もう一度お手数をおかけします。 –

+0

偉大な答えをお祝いします。私はそれを複数回アップヴォートすることができたらいいと思う。 – jsbueno

関連する問題