0

私は現在、を使用する必要のある小さなスクリプトに取り組んでいますgtk.StatusIcon()。どういうわけか、私はそれでいくつかの奇妙な振る舞いをしています。Pythonインタラクティブシェルに入り、次のように入力します。

>> import gtk
>> statusIcon = gtk.status_icon_new_from_file("img/lin_idle.png")

Pygtkは正確に実行する必要があり、システムトレイにアイコン(lin_idle.png)を表示します。

これは正常に機能します

ただし、スクリプトで同じタスクを実行しようとすると、次のようになります。

def gtkInit(self):
    self.statusIcon = gtk.status_icon_new_from_file( "img / lin_idle.png")

gtkInit()呼び出されると、代わりに次のように表示されます。

なぜあなたはGSFKLJFSGDJKHSFDGHJKLを働かないのですか

インタラクティブなPythonシェルと同じ作業ディレクトリでスクリプトを実行したので、画像が見つかると確信しているので、困惑しています...誰かアイデアはありますか?前もって感謝します。

更新:何らかの理由gtk.status_icon_new_from_file()で、スクリプトで数回呼び出した後、最終的にアイコンが作成されますが、残念ながらこの問題は依然として残っています。何がうまくいかないのかについて誰かが何か考えを持っていますか?

要求に応じて:完全なスクリプトは次のとおりです。これは実際には私が作成の初期段階にあるアプリケーションですが、正しくセットアップすれば現時点で機能するので、必要に応じて自由に試してみてください(そして私も助けてください!)、あなたはただimgur開発者キーを取得してそれを入れる必要がありますlinup_control.py

Linup.py

#
#Linup-Linuxのドロップボックスの代替品!
#Nakedsteve脚本の作品
#MITライセンスの下でリリース
#

OSのインポート
インポート時間
ConfigParserをインポートします
linup_controlからインポートLinup

cfg = ConfigParser.RawConfigParser()
#.linuprcファイルがあるかどうかを確認します
home = os.path.expanduser( "〜")

os.path.exists(home + "/。linuprc")でない場合:
    #いや、作ってみよう
    cfg.add_section( "paths")
    cfg.set( "paths"、 "watch_path"、home + "/ Desktop / screenshot1.png")

    #ファイルに書き込みます
    configfileとしてopen(home + "/。linuprc"、 "wb")を使用:
        cfg.write(configfile)
そうしないと:
    cfg.read(home + "/。linuprc")

linup = Linup()

#GUIを作成します(ステータスアイコン、メニューなど)
linup.gtkInit()

#メインループに入り、アップロードするショットがあるかどうかを確認します
#1秒ごと
path = cfg.get( "paths"、 "watch_path")
一方1:
    if(os.path.exists(path)):
        linup.uploadImage(path)
        url = linup.getURL()
        linup.toClipboard(url)
        linup.json = ""

        「スクリーンショットをアップロードしました!」を印刷します
        os.remove(path)
    そうしないと:
        #なぜ私がtime.sleep()を使用しているのか疑問に思っているなら
        #それがないとCPUが残っていることがわかったからです
        #linupの実行中は常に50%。あなたがより良い
        #これを行うための方法、それについて私に連絡してください(私はPythonで比較的新しいです)
        time.sleep(1)

linup_control.py

gtkをインポートする
jsonをインポートする
インポート時間
pycurlをインポートする
OSのインポート

クラスLinup:
    def __init __(self):
        self.json = ""

    def uploadImage(self、path):
        #ステータスアイコンをビジーに設定
        self.statusIcon.set_from_file( "img / lin_busy.png")

        #新しいpycurlインスタンスを作成します
        cu = pycurl.Curl()

        #POST変数を画像と開発キーに設定します
        vals = [
            ("鍵"、"*************")、
            ("画像"、(cu.FORM_FILE、パス))
        ]

        #送信先のURLを設定する
        cu.setopt(cu.URL、 "http://imgur.com/api/upload.json")
        #これにより、imgurによって返されるjsonを取得できます
        cu.setopt(cu.WRITEFUNCTION、self.resp_callback)
        cu.setopt(cu.HTTPPOST、vals)

        #食べて!
        cu.perform()
        cu.close()

        #ステータスアイコンを完了に設定します...
        self.statusIcon.set_from_file( "img / lin_done.png")
        #3秒待つ
        time.sleep(3)
        #アイコンをアイドルに設定します
        self.statusIcon.set_from_file( "img / lin_idle.png")

    #imgurから応答jsonを取得するために使用されます
    def resp_callback(self、buff):
        self.json+=バフ

    #jsonデータから画像のURLを抽出します
    def getURL(self):
        js = json.loads(self.json)
        return js ['rsp'] ['image'] ['original_image']

    #テキスト変数をクリップボードに挿入します
    def toClipboard(self、text):
        cb = gtk.Clipboard()
        cb.set_text(text)
        cb.store()

    #LinupのGUI要素を開始します
    def gtkInit(self):
        self.statusIcon = gtk.StatusIcon()
        self.statusIcon.set_from_file( "img / lin_idle.png")
4

2 に答える 2

4

gtk.mainqba が言ったように関数を呼び出す必要がありますが、 N ミリ秒ごとに関数を呼び出す正しい方法は、gobject.timeout_add関数を使用することです。ほとんどの場合、別のスレッドで GUI を結び付けることができるものを用意したいと思うでしょうが、アイコンだけを持っている場合は必要ありません。StatusIcon にメニューを持たせることを計画している場合を除きます。これが私が変更した部分ですLinup.py

# Enter the main loop, where we check to see if there's a shot to upload
# every 1 second
path = cfg.get("paths","watch_path")
def check_for_new():

    if(os.path.exists(path)):
        linup.uploadImage(path)
        url = linup.getURL()
        linup.toClipboard(url)
        linup.json = ""

        print "Screenshot uploaded!"
        os.remove(path)
    # Return True to keep calling this function, False to stop.  
    return True

if __name__ == "__main__":

    gobject.timeout_add(1000, check_for_new)

    gtk.main()

あなたもimport gobjectどこかに行かなければなりません。

pycurlインストールできないため、これが機能するかどうかはわかりません。

編集:ではlinup_control.py、変更してみます

# Wait 3 seconds
time.sleep(3)
# Set the icon to idle
self.statusIcon.set_from_file("img/lin_idle.png")

gobject.timeout_add(3000, self.statusIcon.set_from_file, "img/lin_idle.png")
于 2009-11-04T23:28:10.240 に答える
1

あなたは2つの間違いを犯しました。1つは重要です。1つはそうではありません。

ストックアイコンを使いたい場合は、まず .set_from_stock( stock_id ) メソッドを使います。独自のアイコンを使用する場合は、.set_from_file(/path/to/img.png) で問題ありません。

もう 1 つの考えは、おそらく主な問題は、gtk アプリケーションを作成するときに gtk.main() 関数を呼び出さなければならないことです。これは、すべてのシグナル処理/ウィンドウ描画およびその他すべての gtk 処理が行われるメインの gtk ループです。これを行わないと、単にアイコンが描画されません。

あなたの場合の解決策は、2 つのスレッドを作成することです。1 つは GUI 用、もう 1 つはアプリ用です。最初のものでは、単に gtk.main() を呼び出します。次に、メイン プログラムのループを配置します。もちろん、python プログラムを呼び出すと、すでに 1 つのスレッドが開始されています:P

スレッドに慣れていない場合は、他の解決策があります。Gtkには、指定された関数を遅延して呼び出す関数があります:

def call_me:
    print "Hello World!"
    gtk.timeout_add( 1000 , call_me )

gtk.timeout_add( 1000 , call_me )
gtk.main()

しかし、現在は廃止されているようです。おそらく彼らはより良い解決策を作ったでしょう。

于 2009-11-04T22:56:04.280 に答える