0

wxpython と wx.lib.pubsub を使用してアプリケーションをプログラミングしています。Python 2.7.3で

1- メニュー項目のあるフレームがあります。このメニューをクリックすると、pubsub によってメッセージが公開されます。

2- このメッセージは (可能であれば) 破棄し、「第 1 レベル」のダイアログを作成します。

3- 「第 1 レベル」ダイアログには、値のリストと「値の追加」ボタンがあります。(注:このような変数のリストは変更できるため、このリストを更新しようとしています)

4- 「値を追加」ボタンをクリックすると、別のメッセージが pubsub によってパブリッシュされます。

5- このメッセージは「第 2 レベル」ダイアログを作成するため、新しい変数の新しい名前を書き込むことができます。

6- この「第 2 レベル」ダイアログには「続行」ボタンがあり、次の 2 つの結果があります。

最初のもの: Self.Destroy();

2 つ目: ステップ 2 に進みます。つまり、「第 1 レベル」のダイアログを破棄して、再度作成します。

その時点までプログラムは正常に動作しているように見えますが、「最初のレベル」のダイアログに変数を「追加」し終えると、それを破棄すると、ステップ 1 で述べたメイン フレームに戻ることができなくなります。

なぜこうなった?

すべてのダイアログは、ShowModal() を介して表示されます。ただし、Show() のみを使用すると問題なく動作するように見えますが、プログラムには多くのメニューと項目があるため、ShowModal() を使用することをお勧めします。Show() では機能するが、ShowModal() では機能しない理由は何ですか?

私がやりたいタスクを実行するためのより簡単な方法があれば、それはありがたいです。

import wx
from wx.lib.pubsub import Publisher as pub

class itemReceiver(object):
    def __init__(self):
        pub.subscribe(self.__OnShowDialog, 'show.dialog')

    def __OnShowDialog(self, message):
        self.dlgParent = message.data[0]
        print str(self.dlgParent)
        self.valuesToShow = message.data[1]
        print self.valuesToShow
        #try to destroy dialog before creating a new one
        try:
            self.manageParametersDialog.Destroy()
        except:
            pass   
        self.manageParametersDialog = manageParamsDialog(self.dlgParent,  self.valuesToShow)
        print "ready to show first level dialogue"
        self.manageParametersDialog.ShowModal() #if .Show() instead, there is no problem

class secondaryReceiver(object):
    def __init__(self):
        pub.subscribe(self.__OnShowDialog, 'add.item')

    def __OnShowDialog(self, message):
        dlgParent = message.data[0]
        dlgGrandParent = message.data[1]
        self.variableList = message.data[2]
        editParameterDialog = editParamDlg(dlgParent, dlgGrandParent, self.variableList)
        editParameterDialog.ShowModal()

class manageParamsDialog (wx.Dialog):
    def __init__(self, parent, valueList):
        self.valueList = valueList
        self.parent = parent
        wx.Dialog.__init__(self, parent, -1, "first level dialogue", style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER) 
        sizer=wx.BoxSizer(wx.VERTICAL)
        self.optionList = wx.ListBox(self, -1, size=(200, 70), choices = valueList)
        sizer.Add(self.optionList)
        addButton = wx.Button(self, -1, 'Add New')
        self.Bind(wx.EVT_BUTTON, self.OnButton, addButton)
        sizer.Add(addButton)
        cancelButton = wx.Button(self, -1, 'Cancel')
        self.Bind(wx.EVT_BUTTON, self.OnCancel, cancelButton)
        sizer.Add(cancelButton)
        self.SetSizer(sizer)
        self.Fit()
    def OnButton (self, e):
        pub.sendMessage('add.item', [self, self.parent, self.valueList])
    def OnCancel(self,e):
        self.Destroy()

class editParamDlg(wx.Dialog):
    def __init__(self, parent, grandParent, variableList):
        self.variableList = variableList
        self.grandParent = grandParent
        wx.Dialog.__init__(self, parent, -1, "second level dialogue", style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER) 
        hboxSizer = wx.BoxSizer(wx.HORIZONTAL)
        self.textInput = wx.TextCtrl(self, -1)
        hboxSizer.Add(self.textInput)
        addButton = wx.Button(self, -1, 'Continue')
        self.Bind(wx.EVT_BUTTON, self.OnAdd, addButton)
        hboxSizer.Add(addButton)
        cancelButton = wx.Button(self, -1, 'Cancel')
        self.Bind(wx.EVT_BUTTON, self.OnCancel, cancelButton)
        hboxSizer.Add(cancelButton)
        self.SetSizer(hboxSizer)
        self.Fit()

    def OnAdd(self, e):
        self.variableList.append(self.textInput.GetValue())
        self.Destroy()
        pub.sendMessage('show.dialog',[self.grandParent, self.variableList])
    def OnCancel(self,e):
        self.Destroy()

class ToolbarFrame(wx.Frame):
#this ToolbarFrame is the main window, with a Toolbar and a white panel below.
    def __init__(self, parent, id):    
        wx.Frame.__init__(self, parent, id, "this is a frame", size=(480, 320))
        myPanel = wx.Panel(self)
        myPanel.SetBackgroundColour("White")
        menuBar = wx.MenuBar()
        fileMenu = wx.Menu()
        menuItem = wx.MenuItem(fileMenu, -1, "menu item", "opens dialog via pubsub") 
        self.Bind(wx.EVT_MENU, self.OnMenuItem, menuItem)
        fileMenu.AppendItem(menuItem)
        menuBar.Append(fileMenu, "File")
        self.SetMenuBar(menuBar)


    def OnMenuItem(self, e):
        pub.sendMessage('show.dialog', [self, ["one", "two", "three"]])


app = wx.PySimpleApp()
frame = ToolbarFrame(parent=None, id=-1)
frame.Show()
newItemListener = itemReceiver()
editParameterListener = secondaryReceiver()
app.MainLoop()
4

1 に答える 1

1

次のようにsecondaryRecieverを変更してみてください

class secondaryReceiver(object):
    def __init__(self):
        pub.subscribe(self.__OnShowDialog, 'add.item')

    def __OnShowDialog(self, message):
        dlgParent = message.data[0]
        dlgGrandParent = message.data[1]
        self.variableList = message.data[2]
        editParameterDialog = editParamDlg(dlgParent, dlgGrandParent, self.variableList)
        editParameterDialog.ShowModal()
        #this line will not execute till the dialog closes
        self.dlgParent.optionList.SetItems(editParameterDialog.variableList)
        editParameterDialog.Destroy()

editParamDlgも変更します

def OnAdd(self, e):
    self.variableList.append(self.textInput.GetValue())
    self.Close()

問題は、そのOnAddからshow.modalを呼び出すことでした...既存のウィンドウを破棄してから新しいウィンドウを開こうとします...しかし、古いウィンドウは破棄されませんでした...これにより、奇妙な残骸が残り、エラー...そして本当にやりたいことは、アイテムリストを更新することだけです...

于 2014-11-18T14:22:11.487 に答える