-2

これは私のスクリプトです。何らかの理由で、もう機能しません。それは以前に行っています。誰かが潜在的なエラーを追跡できますか?

    #! /usr/bin/env python

import wx
import os
TRAY_TOOLTIP = 'jmtpfs mounter'

def create_menu_item(menu, label, func):
    item = wx.MenuItem(menu, -1, label)
    menu.Bind(wx.EVT_MENU, func, id=item.GetId())
    menu.AppendItem(item)
    return item

class TaskBarIcon(wx.TaskBarIcon):
    def __init__(self):
        super(TaskBarIcon, self).__init__()
    self.off=wx.IconFromBitmap(wx.Bitmap("android_off.png"))
    self.SetIcon(self.off)
        self.Bind(wx.EVT_TASKBAR_LEFT_DOWN, self.on_left_down)
    def CreatePopupMenu(self):
        menu = wx.Menu()
        create_menu_item(menu, 'Mount', self.mount)
        create_menu_item(menu, 'UnMount', self.unmount)
        menu.AppendSeparator()
        create_menu_item(menu, 'Exit', self.on_exit)
        return menu
    def on_left_down(self, event):
        print 'Tray icon was left-clicked.'
    def mount(self, event):
        retvalue = os.system("jmtpfs ~/Nexus")
        print retvalue
    self.on=wx.IconFromBitmap(wx.Bitmap("android_on.png"))
    self.SetIcon(self.on)
    def unmount(self, event):
        retvalue = os.system("fusermount -u ~/Nexus")
    print retvalue
    self.off=wx.IconFromBitmap(wx.Bitmap("android_off.png"))
    self.SetIcon(self.off)
    def on_exit(self, event):
        wx.CallAfter(self.Destroy)

def main():
    app = wx.PySimpleApp()
    TaskBarIcon()
    app.MainLoop()

if __name__ == '__main__':
    main()

トレースを実行すると、次のようになります。

mounter.py(17): self.SetIcon(self.off) --- モジュール名: _windows、funcname: SetIcon _windows.py(2174):ウィンドウを返す .TaskBarIcon_SetIcon(*args, **kwargs) mounter.py(18) : self.Bind(wx.EVT_TASKBAR_LEFT_DOWN, self.on_left_down) --- modulename: _core, funcname: Bind _core.py(3916): assert isinstance(event, wx.PyEventBinder) _core.py(3917): assert handler is None or callable(handler) _core.py(3918): assert source is None or hasattr(source, 'GetId') _core.py(3919): if source is not None: _core.py(3921): event.Bind(self 、id、id2、ハンドラ)
--- modulename: _core, funcname: Bind _core.py(3994): for et in self.evtType: _core.py(3995): target.Connect(id1, id2, et, function) --- modulename: _core, funcname: Connect _core.py(3875): return core .EvtHandler_Connect(*args, **kwargs) _core.py(3994): for et in self.evtType: mounter.py(44): app.MainLoop() -- - modulename: _core, funcname: MainLoop _core.py(8010): wx.PyApp.MainLoop(self) --- modulename: _core, funcname: MainLoop _core.py(7306): return core .PyApp_MainLoop(*args, **クワーグス)

4

1 に答える 1

2

PyDev でコードをデバッグしているときにエラーを再現できませんでした。ただし、コードが実行される可能性があるため、修正しなければならないエラーが多数見つかりました。それらを修正した後、コードは正常に実行されました。

まず、エラーは、self.Bind(wx.EVT_TASKBAR_LEFT_DOWN, self.on_left_down)呼び出しの「ハンドラー」が であることを示していますNone。この場合、それはself.on_left_downisを意味しますNone。ただし、 function があることがわかりますon_left_down(self, event)。これが、コードに問題があることを示す最初のヒントでした。2 番目のヒントは、スタック トレースBind()に行の一部としてその呼び出しが含まれているように見えることでしたself.SetIcon(self.off)。これは意味がありません。

その時、あなたのへこみがひどいことに気づきました。Java のような言語では、 の間のすべてが{}関数の一部であるため、インデントは単にコードを読みやすくするためのものです。Python のインデントでは、はるかに重要です。それは、何かが関数の一部であるかどうかを示す方法です。コード行がまだループの一部であるかどうかをどのように判断しますか? インデントを確認します。__init__()mount()、およびunmount()すべてに左にインデントされた行が含まれているため、 が実行される前__init__()に実行され、これらの値につながる可能性がありNoneます。

第二に、古いチュートリアルを使用している必要がありますwx.PySimpleApp。コードを実行する前に、独自の簡単なwx.Appコードを作成する必要がありました (宣言を含めて、全体wx.Appはわずか 4 行の長さでした。これを自分で行う方法の簡単な例を見つけることができると確信しています)。

最後に、嘆願:特に言語に精通していない場合は、チュートリアルで見つけたコードを盲目的に使用しないでください。あなたは Python プログラマーではないと言いましたが、なぜ wxPython を選んだのですか? C.を知っていますか?wxPython は、C 用の GUI ツールキットである wxWidgets に基づいています。Java を知っていますか? Java 用の GUI ツールキットは多数あります。あなたが理解できる言語で必要なことを行うものを見つけることができると確信しています. 理解できないコードをアプリケーションに入れることは、実際には、失敗する可能性のある新しい部分を入れるだけであり、失敗した場合、それを修正する方法はありません。

私はあなたを知りませんし、あなたの専門知識も知らないので、今回は疑いの余地を与えますが、次回はあなたの側でさらに多くの努力をする必要があるか、回答を投稿しません.

幸運を祈ります。

于 2012-09-06T06:12:57.373 に答える