0

私は wxPython を使い始めたばかりで、これが私がやりたいことです:

a) フレーム (その中にパネルがある) とそのパネルのボタンを表示します。b) ボタンを押すと、ダイアログ ボックスが表示されます (選択肢から選択できます)。c) ダイアログ ボックスで [OK] を押すと、ダイアログ ボックスは消える (破棄される) はずですが、元のフレーム + パネル + ボタンはまだそこにあります。d) そのボタンをもう一度押すと、ダイアログ ボックスが再び表示されます。

私のコードを以下に示します。残念ながら逆効果です。あれは、

a) 選択ダイアログ ボックスが最初に表示されます (つまり、TopLevelframe+button が表示されないため、ボタンをクリックせずに)。

b) ダイアログ ボックスで [OK] をクリックすると、ボタン付きのフレームが表示されます。

c) ボタンをもう一度クリックしても効果がありません (つまり、ダイアログ ボックスは再び表示されません)。

私は何を間違っていますか?フレームが初期化されるとすぐに (.Show() が呼び出される前であっても)、ダイアログ ボックスが初期化されて自動的に表示されるようです。

Python 2.6を搭載したWindowsXPでEclipse + Pydevを使用してこれを行っています

============ファイル:MainFile.py===============

import wx
import MyDialog   #This is implemented in another file: MyDialog.py

class TopLevelFrame(wx.Frame):

    def __init__(self,parent,id):    
        wx.Frame.__init__(self,parent,id,"Test",size=(300,200))
        panel=wx.Panel(self)
        button=wx.Button(panel, label='Show Dialog', pos=(130,20), size=(60,20))

        # Bind EVENTS --> HANDLERS. 
        button.Bind(wx.EVT_BUTTON, MyDialog.start(self))  


# Run the main loop to start program.         
if __name__=='__main__':
    app=wx.PySimpleApp()    
    TopLevelFrame(parent=None, id=-1).Show()  
    app.MainLoop()

============ファイル:MyDialog.py===============

import wx

def start(parent):
    inputbox = wx.SingleChoiceDialog(None,'Choose Fruit', 'Selection Title',
                                     ['apple','banana','orange','papaya'])
    if inputbox.ShowModal()==wx.ID_OK:
        answer = inputbox.GetStringSelection()
        inputbox.Destroy()
4

1 に答える 1

3

これを行う方法はいくつかありますが、コードの変更を最小限に抑えるには、

def start(parent):に変更

def start(parent, evt):

そしてbutton.Bind(wx.EVT_BUTTON, MyDialog.start(self))に変更

    button.Bind(wx.EVT_BUTTON, lambda evt: MyDialog.start(self, evt))

つまり、Bind の 2 番目の引数はイベントを受け取る関数である必要があり、ボタンがクリックされたときにダイアログ ボックスを作成する必要があります。 lambdaこれを、parent と evt も受け取る関数にし (バージョン >2.5 では functools.partial を使用することもできます)、ボタンがクリックstartされると、ダイアログを作成するために呼び出されます。

コードで何が起こっているのかよくわかりませんが、startBind への最初の呼び出しでダイアログを呼び出して作成し、最初から戻り値を Bind に渡しているようですNone

注 1 より詳細には、ここでラムダを使用する理由は、Bind が wx.EVT_BUTTON のような wx.PyEventBinder のような形式を持つ必要がありBind(event, handler)evteventwx.Eventまたはwx.CommandEvent. (何かが起こったときに何をすべきかを言っているだけなので、ここには再帰はありませんが、そのことはまだ起こっていないので、イベントは作成されていません。イベントが発生すると、それは wx で表されます.Event (クリックされたときのマウスの位置など、イベントに関する情報が含まれます)handler

注2 私の回答では、それが最も簡単だと思ったので、最小限の変更であなたの質問に答えようとしました。以下のコードの方がわかりやすいかもしれません (イベントを作成するウィジェット内でイベントを処理するのが一般的に最もわかりやすいかもしれません):

def start2(parent):
    inputbox = wx.SingleChoiceDialog(parent,'Choose Fruit', 'Selection Title',
                                     ['apple','banana','orange','papaya'])
    if inputbox.ShowModal()==wx.ID_OK:
        answer = inputbox.GetStringSelection()
    inputbox.Destroy()

class TopLevelFrame2(wx.Frame):

    def __init__(self,parent,id):    
        wx.Frame.__init__(self,parent,id,"Test",size=(300,200))
        panel=wx.Panel(self)
        button=wx.Button(panel, label='Show Dialog', pos=(130,20), size=(60,20))

        # Bind EVENTS --> HANDLERS. 
        button.Bind(wx.EVT_BUTTON, self.OnClick)  

    def OnClick(self, evt):
        start2(self)
于 2010-04-26T18:55:53.667 に答える