2011-06-07 38 views
1

我試圖將用戶選擇的目錄傳回給名爲ChooseRoot的wx.TextCtrl。迄今爲止這還沒有奏效。
我在做什麼錯?嘗試了不同的事情,但是它掛起或我得到這個錯誤消息。wxPython中wx.TextCtrl的問題設置值

OOP的新手,請幫助新手熱切學習。 =)

Traceback (most recent call last):
File "F:\Indexinator3000_x64.pyw", line 78, in OnChooseRoot
self.ChooseRoot.SetValue("Hello")
AttributeError: 'MainPanel' object has no attribute 'ChooseRoot'

import wx 

ID_EXIT = 110 

class MainPanel(wx.Panel): 
    def __init__(self, parent, id): 
     wx.Panel.__init__(self, parent, id) 
     self.parent = parent 

     #------------- Setting up the buttons 
     self.Run = wx.Button(self, label="Run") 
     self.Run.Bind(wx.EVT_BUTTON, self.OnRun) 
     self.ExitB = wx.Button(self, label="Exit") 
     self.ExitB.Bind(wx.EVT_BUTTON, self.OnExit) 

     #------------- Setting up Static text 
     self.labelChooseRoot = wx.StaticText(self, label ="Root catalog: ") 
     self.labelScratchWrk = wx.StaticText(self, label ="Sratch workspace: ") 
     self.labelMergeFile = wx.StaticText(self, label ="Merge file: ") 

     #------------ Setting up inputtext 
     self.ChooseRoot = wx.TextCtrl(self, -1, size=(210,-1)) 
     self.ChooseRoot.Bind(wx.EVT_LEFT_UP, self.OnChooseRoot) 
     self.ScratchWrk = wx.TextCtrl(self, -1, size=(210,-1)) 
     self.MergeFile = wx.TextCtrl(self, -1, size=(210,-1)) 


     #------------- Setting up the outputbox 
     self.Output = wx.TextCtrl(self, style=wx.TE_MULTILINE|wx.TE_READONLY) 

     #------------- Setting up the sizer 
     SizerF = wx.FlexGridSizer(3,2,5,5) 
     SizerF.Add(labelChooseRoot)  #row 1, col 1 
     SizerF.Add(ChooseRoot)   #row 1, col 2 
     SizerF.Add(labelScratchWrk)  #row 2, col 1 
     SizerF.Add(ScratchWrk)   #row 2, col 2 
     SizerF.Add(labelMergeFile)  #row 3, col 1 
     SizerF.Add(MergeFile)   #row 3, col 2 

     SizerB = wx.BoxSizer(wx.VERTICAL) 
     SizerB.Add(Run, 1, wx.ALIGN_RIGHT|wx.ALL, 5) 
     SizerB.Add(ExitB, 0, wx.ALIGN_RIGHT|wx.ALL, 5) 

     Sizer1 = wx.BoxSizer() 
     Sizer1.Add(SizerF, 0, wx.ALIGN_RIGHT | wx.EXPAND | wx.ALL, 10) 
     Sizer1.Add(SizerB, 0, wx.ALIGN_RIGHT | wx.EXPAND | wx.ALL) 

     Sizer2 = wx.BoxSizer() 
     Sizer2.Add(Output, 1, wx.EXPAND | wx.ALL, 5) 

     SizerFinal = wx.BoxSizer(wx.VERTICAL) 
     SizerFinal.Add(Sizer1, 0, wx.ALIGN_RIGHT | wx.EXPAND | wx.ALL) 
     SizerFinal.Add(Sizer2, 1, wx.ALIGN_RIGHT | wx.EXPAND | wx.ALL) 


     self.SetSizerAndFit(SizerFinal) 

    #--- START EVENT HANDLERS 

    def OnChooseRoot(self, Event=None): 
     # In this case we include a "New directory" button. 
     dlg = wx.DirDialog(self, "Choose a directory:", 
          style=wx.DD_DEFAULT_STYLE 
          #| wx.DD_DIR_MUST_EXIST 
          #| wx.DD_CHANGE_DIR 
          ) 

     # If the user selects OK, then we process the dialog's data. 
     # This is done by getting the path data from the dialog - BEFORE 
     # we destroy it. 
     if dlg.ShowModal() == wx.ID_OK: 
      RootPath = dlg.GetPath() 
      self.ChooseRoot.SetValue(RootPath) 

     # Only destroy a dialog after you're done with it. 
     dlg.Destroy() 

    def OnRun(self, Event=None): 
     #First check if any of the boxes is empty 
     pass 

    def OnExit(self, Event=None): 
     self.GetParent().Close() 


    #--- END EVENT HANDLERS 

class MainWindow(wx.Frame): 
    def __init__(self, parent, id, title): 
     wx.Frame.__init__(self, parent, wx.ID_ANY, title, size = (430,330), 
          style = wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE | wx.STAY_ON_TOP) 
     self.CreateStatusBar() 
     #------------- Setting up the menu 
     filemenu = wx.Menu() 
     filemenu.Append(ID_EXIT, "E&xit", "Exit the program") 
     #------------- Creating the menu 
     menubar = wx.MenuBar() 
     menubar.Append(filemenu, "&File") 
     self.SetMenuBar(menubar) 
     #---------- Setting menu event handlers 
     wx.EVT_MENU(self, ID_EXIT, self.OnExit)      
     #--- Add MainPanel 
     self.Panel = MainPanel(self, -1) 

     self.SetMaxSize(self.GetSize()) #Sets the Maximum size the window can have 
     self.SetMinSize(self.GetSize()) #Sets the Minimum size the window can have 
     #Centre on Screen 
     self.CentreOnScreen() 

     ###---- SHOW THE WINDOW 
     self.Show(True) 

    def OnExit(self, event): 
     self.Close(True) # Close the Frame 
    #--- END EVENT HANDLERS --------------------------------- 



if __name__=='__main__': 

    try: 
     app = wx.PySimpleApp() 
     frame = MainWindow(None, -1, "IndexGenerator") 
     app.MainLoop() 
    finally: 
     del app 

回答

3

請仔細閱讀通知:那我給你在以前的question。尤其是:

  • 的Widget使用對象的屬性,所以你不要鬆跟蹤它們的(self.ChooseRoot =...
  • 使用更desriptive部件名稱(self.labelChooseRoot

__init__法(又名構造函數)你跟蹤你的小部件。您必須將它們添加到您的MainPanel對象中作爲屬性。

class MainPanel(wx.Panel): 
    def __init__(self, parent, id): 
     ... 
     self.ChooseRoot = wx.TextCtrl(self, size=(210, -1)) 
     ... 

    def OnChooseRoot(self, event=None): 
     ... 
     self.ChooseRoot.SetValue(RootPath) 
     ... 

我也會推薦一些關於面向對象概念的閱讀。也許你可以從here開始。

編輯: 你幾乎得到它的工作。這個想法沒問題,你只是忘了幾個地方。我已更新您的代碼以符合我的「標準」,刪除了一些不必要的複製/粘貼內容以及其他一些小調整。使用一些比較軟件,並做一個仔細的比較,如果你喜歡看到的變化。

import wx 

ID_EXIT = 110 

class MainPanel(wx.Panel): 
    def __init__(self, parent): 
     wx.Panel.__init__(self, parent) 

     self.buttonRun = wx.Button(self, label="Run") 
     self.buttonRun.Bind(wx.EVT_BUTTON, self.OnRun) 
     self.buttonExit = wx.Button(self, label="Exit") 
     self.buttonExit.Bind(wx.EVT_BUTTON, self.OnExit) 

     self.labelChooseRoot = wx.StaticText(self, label ="Root catalog: ") 
     self.labelScratchWrk = wx.StaticText(self, label ="Scratch workspace: ") 
     self.labelMergeFile = wx.StaticText(self, label ="Merge file: ") 

     self.textChooseRoot = wx.TextCtrl(self, size=(210, -1)) 
     self.textChooseRoot.Bind(wx.EVT_LEFT_UP, self.OnChooseRoot) 
     self.textScratchWrk = wx.TextCtrl(self, size=(210, -1)) 
     self.textMergeFile = wx.TextCtrl(self, size=(210, -1)) 
     self.textOutput = wx.TextCtrl(self, style=wx.TE_MULTILINE | wx.TE_READONLY) 

     self.sizerF = wx.FlexGridSizer(3, 2, 5, 5) 
     self.sizerF.Add(self.labelChooseRoot) #row 1, col 1 
     self.sizerF.Add(self.textChooseRoot) #row 1, col 2 
     self.sizerF.Add(self.labelScratchWrk) #row 2, col 1 
     self.sizerF.Add(self.textScratchWrk) #row 2, col 2 
     self.sizerF.Add(self.labelMergeFile) #row 3, col 1 
     self.sizerF.Add(self.textMergeFile) #row 3, col 2 

     self.sizerB = wx.BoxSizer(wx.VERTICAL) 
     self.sizerB.Add(self.buttonRun, 1, wx.ALIGN_RIGHT|wx.ALL, 5) 
     self.sizerB.Add(self.buttonExit, 0, wx.ALIGN_RIGHT|wx.ALL, 5) 

     self.sizer1 = wx.BoxSizer() 
     self.sizer1.Add(self.sizerF, 0, wx.ALIGN_RIGHT | wx.EXPAND | wx.ALL, 10) 
     self.sizer1.Add(self.sizerB, 0, wx.ALIGN_RIGHT | wx.EXPAND | wx.ALL) 

     self.sizer2 = wx.BoxSizer() 
     self.sizer2.Add(self.textOutput, 1, wx.EXPAND | wx.ALL, 5) 

     self.sizerFinal = wx.BoxSizer(wx.VERTICAL) 
     self.sizerFinal.Add(self.sizer1, 0, wx.ALIGN_RIGHT | wx.EXPAND | wx.ALL) 
     self.sizerFinal.Add(self.sizer2, 1, wx.ALIGN_RIGHT | wx.EXPAND | wx.ALL) 

     self.SetSizerAndFit(self.sizerFinal) 


    def OnChooseRoot(self, event): 
     dlg = wx.DirDialog(self, "Choose a directory:", style=wx.DD_DEFAULT_STYLE) 
     if dlg.ShowModal() == wx.ID_OK: 
      root_path = dlg.GetPath() 
      self.textChooseRoot.SetValue(root_path) 
     dlg.Destroy() 

    def OnRun(self, event): 
     #First check if any of the boxes is empty 
     pass 

    def OnExit(self, event): 
     self.GetParent().Close() 


class MainWindow(wx.Frame): 
    def __init__(self): 
     wx.Frame.__init__(self, None, title="IndexGenerator", size=(430, 330), 
          style=((wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE | 
            wx.STAY_ON_TOP)^wx.RESIZE_BORDER)) 
     self.CreateStatusBar() 

     self.fileMenu = wx.Menu() 
     self.fileMenu.Append(ID_EXIT, "E&xit", "Exit the program") 
     self.menuBar = wx.MenuBar() 
     self.menuBar.Append(self.fileMenu, "&File") 
     self.SetMenuBar(self.menuBar) 
     wx.EVT_MENU(self, ID_EXIT, self.OnExit)      

     self.Panel = MainPanel(self) 

     self.CentreOnScreen() 
     self.Show() 

    def OnExit(self, event): 
     self.Close() 

if __name__ == "__main__": 
    app = wx.App(False) 
    frame = MainWindow() 
    app.MainLoop() 
+0

再次問候。我試過這個,但pytonw.exe死機。這就是爲什麼我認爲這是錯的。主程序是'如果__name __ == '__ main__': 嘗試: 應用程式= wx.PySimpleApp() 幀=主窗口(無,-1, 「IndexGenerator」) app.MainLoop() 最後: 德爾應用程序'也許這會導致它?我是否應該將自己添加到sizer中?試圖添加自己所有,但sizer和pytonw.exe仍然掛起。抱歉的佈局,格式化評論的問題。 – sekstiseks 2011-06-07 11:15:53

+0

請使用整個可運行程序更新您的問題。 – Fenikso 2011-06-07 11:45:58

+0

在這裏,你去爵士。 =) – sekstiseks 2011-06-07 12:02:51