2013-07-10 12 views
5

私は与えられたイベントで私に通知するスクリプトをPythonで作成しました。私は警告ウィンドウを生成するために、以下の機能を使用しています :Tkinter TkMessageBoxがクリックしても閉じられないOK

def window_warn(): 
    ''' 
    This function will throw up a window with some text 
    ''' 
    #These two lines get rid of tk root window 
    root = Tkinter.Tk() 
    root.withdraw() 
    #tkMessageBox.deiconify() 
    TkMessageBox.showwarning("New Case", "You have a new case\n Please restart pycheck") 
    return 

ウィンドウが細かい描画しますが、私は[OK]をクリックすると、ウィンドウが押されたボタンのある場所にとどまります。私はxfceを使っています。 OKをクリックしてウィンドウを閉じる方法はありますか?

のコメントはこれがそう完全にするために、周囲のコードをどうするかもしれ示さ:

print "Just started newcase check" 
while True: 
    if "Uncommitted" in webpage: 
     print "oh look, 'Uncommitted' is in the url returned from the last function" 
     #If this hits we call a notification window 
     window_warn() 
     print "sleeping" 
     time.sleep(10) 

     webpage = scrape_page() 
    else: 
     print "nothing" 
     time.sleep(20) 
     webpage = scrape_page() 
+0

コンテキストの関数を呼び出すコードを追加しました – Rqomey

+0

また、これをインタラクティブシェルで実行するとうまくいきます。私が戻り値 'ok 'を捕まえていないので、それが正しいかどうかわからない – Rqomey

答えて

6

、関数から戻る前にroot.update()を呼び出してみてください。これは、すべての保留中のTk/Xウィンドウイベントを処理します。

(理想的には、ウィンドウを表示する前にメインイベントループを確立するだろうが、それはあなたの全体のプログラムは、常に動作しない場合があり、イベント駆動型であることを前提としています。)

+0

ありがとう、これはちょうどそれであるようだ! – Rqomey

+0

申し訳ありませんが、メインイベントループの意味を説明してください。プログラムは毎分Webページをスキャンします。 – Rqomey

+0

Tkinterプログラムは通常、Tkを "上に"置いてコールバックで実行されるコードで構成されています。つまり、Tkの部分を設定し、mainloopを呼び出し、Tkがあなたに電話するのを待ちます。プログラムと対話するユーザーに送信します。しかし、それはおそらくあなたの場合は少し実用的ではありません。 – Fredrik

0

あなたがイベントに応答するプログラムを有効にするroot.mainloop()を呼び出す必要があります。

+0

' tkmb.showwarning( "New Case"、 "You have a new case")の直後に 'root.mainloop()'を呼びました。ハングアップするだけで何もしません。それは特定の方法で呼び出される必要がありますか?ありがとう – Rqomey

+0

ダイアログが閉じるまでダイアログブロックを開くので、ダイアログを開く前に_実行している必要があります。 –

0

コードで問題になるのは、関数window_warnを呼び出すたびに新しいTk要素を作成することです。これはあなたの問題の原因ではないかもしれませんが、複数のTk要素を作成するのは避けるべきではありません。例えば、最初にルート要素を初期化し、showwarningにのみコールまま:

root = Tkinter.Tk() 
root.withdraw() 

def window_warn(): 
    '''This function will throw up a window with some text''' 
    tkMessageBox.showwarning("New Case", "You have a new case\n Please restart pycheck") 
    return 

print "Just started newcase check" 
while True: 
    # ... 
+0

ここにあなたのポイントがあります。関数外のルートを呼び出すと、その関数内でroot.update()を実行することはできません。おそらく私はそれを間違った方法で設定しています。最初にroot = Tkinter.Tk()を起動する最初の実行セクションが必要です。ターミナルボックス内で実行していますので、現時点で正常に動作しているようです(ウィンドウの重複はありません) – Rqomey

+0

同じモジュール内で定義されている場合、関数内のコードは引き続きrootにアクセスできます(同じモジュール内のコードに直接アクセスできる場合でもPythonでは "グローバル"変数と呼ばれます)。私はTkのルートウィンドウを再作成するのに大きな害はないと思う。 – Fredrik

0

私はそれが道をTISんでした:

import Tkinter as tk 
import tkMessageBox 
root = tk.Tk() 
root.withdraw() 
t = tkMessageBox.askyesno ('Title','Are you sure?') 
if t: 
    print("Great!!!") 
    root.update() 
else: 
    print("Why?") 
    root.update() 
関連する問題