wxPython将表单代码放在离散的.py文件中(不使用pubsub)

时间:2014-09-01 11:37:11

标签: python wxpython

我正在将一个基于Excel / VBA的小应用程序迁移到wxPython / SQLite3,随后学习后者。随着时间的推移,我发现导航代码变得越来越笨拙 - 目前只有880行,但它比我以前管理的要多一些 - 所以想知道是否有一个简单的解决方案,将每个表单的表单代码分别放在离散的.pys中。

例如,在我当前.py的底部,我有一个启动主窗体的位:

class AuditApp(wx.App):
  def OnInit(self):
    self.aframe = audFrame(None, -1, "Audits Manager")
    self.aframe.Show(True)
    self.SetTopWindow(self.aframe)  # has to be *after* the Show()
    return True

def main():
  app = AuditApp(0)
  app.MainLoop()

if __name__ == '__main__':
  main()

该audFrame当前显示一个菜单和一个列表:

class audFrame(wx.Frame):
  def __init__(self, parent, id, title):    
    wx.Frame.__init__(self, parent, id, title)
    self.scwd = os.getcwd()
    if AppCompiled:
      image = "/home/robyn//dev/Audits/FoggyM.jpg"
    else:
      image = self.scwd + "/FoggyM.jpg"
    self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
    self.bg = wx.Bitmap(image)
    self._width, self._height = self.bg.GetSize()
    # Menu Section
    audmbar = wx.MenuBar()
    mfile = wx.Menu()
    medit = wx.Menu()
    mhelp = wx.Menu()
    mfile.Append(101, "Post-Op &Times", "Post-Op Stay in Minutes")
    mfile.Append(102, "&Patient Satisfaction", "Post-discharge telephone interview")
    mfile.AppendSeparator()
    mquit = wx.MenuItem(mfile, 110, "&Quit\tCtrl+Q", "Leave Audits Manager")
    mfile.AppendItem(mquit)
    mhelp.Append(150, "&Help", "Audit Manager Help")
    mhelp.AppendSeparator()
    mhelp.Append(159, "&About AuditsMgr", "About Audits Manager")
    audmbar.Append(mfile, "&Modules")
    audmbar.Append(medit, "&Edit")
    audmbar.Append(mhelp, "&Help")
    # Data
    self.mconn = self.doConnect()
    self.mcurs = self.mconn.cursor()
    # "SELECT patid, anaesthetist, proctype, intvdate FROM interv ORDER BY intvdate"
    self.mcurs.execute("SELECT patid || '  ' || intvdate || '  ' || proctype || '  ' || anaesthetist AS intvlist FROM interv")
    patList = [item[0] for item in self.mcurs.fetchall()]
    # Top
    line01 = wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL)
    pnlTop = wx.Panel(self, -1, style=wx.SUNKEN_BORDER|wx.TAB_TRAVERSAL)
    BxSzr1 = wx.BoxSizer(wx.HORIZONTAL)
    BxSzr1.Add(pnlTop, 0, wx.ALL, 5)
    self.listBox1 = wx.ListBox(choices=patList, id=160, name='Results', parent=pnlTop, 
                    pos=wx.Point(20, 20), size=wx.Size(450, 300), style=0)
    self.listBox1.SetBackgroundColour(wx.Colour(255, 255, 128))
    #self.listBox1.Bind(wx.EVT_LISTBOX, self.OnListBox1Listbox, id=wxID_FRAME1LISTBOX1)
    btnSizer = wx.BoxSizer(wx.HORIZONTAL)
    self.btnFind = wx.Button(self, 180, u"&Find", wx.DefaultPosition, wx.DefaultSize, 0)        
    self.btnClose = wx.Button(self, 181, u"&Close", wx.DefaultPosition, wx.DefaultSize, 0)
    btnSizer.Add(self.btnFind, 0, wx.ALL|wx.EXPAND, 5)
    btnSizer.Add(self.btnClose, 0, wx.ALL|wx.EXPAND, 5)
    # Main Sizer
    MainSizer = wx.BoxSizer(wx.VERTICAL)
    MainSizer.Add(BxSzr1, 14, wx.ALL|wx.EXPAND, 5)    
    MainSizer.Add(line01, 0, wx.ALL|wx.EXPAND, 5)    
    MainSizer.Add(btnSizer, 1, wx.ALIGN_RIGHT, 5)        
    """
    ====> MAIN LAYOUT CODE <====
    """
    self.Size = wx.Size(1000, 700)
    self.SetMenuBar(audmbar)
    self.CreateStatusBar()
    self.SetSizer(MainSizer)
    self.Layout()
    self.Centre(wx.BOTH)
    self.Bind(wx.EVT_MENU, self.doPOTimes, id = 101)
    self.Bind(wx.EVT_MENU, self.doInterv, id = 102)
    self.Bind(wx.EVT_MENU, self.onQuit, id = 110)
    self.Bind(wx.EVT_MENU, self.onHelp, id = 150)
    self.Bind(wx.EVT_MENU, self.onAbout, id = 159)
    self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
    self.Bind(wx.EVT_BUTTON, self.clkFind, id = 180)
    self.Bind(wx.EVT_BUTTON, self.onQuit, id = 181)

  def clkFind(self, event):
  #  findRec = wx.MessageDialog(self, )
  #  self.popForm()
    event.Skip()

  def clkClose(self, event):
    self.curs.close()
    self.conn.close()
    self.Close()

  def doPOTimes(self, event):
    frm = frmTimes(None, -1, "Post-Op Times")
    frm.Show()

  def doInterv(self, event):
    frm = frmIntervw(None, -1, "Post-Discharge Interview")
    frm.Show()

  def doConnect(self):
    conStr = "/home/robyn/data/audits.db"
    return sqlite3.connect(conStr)

  def onHelp(self, event):
    pass

菜单会显示其他表格和对话。我想知道是否有可能将代码放在离散的.py中。

我看了一下pubsub,但它看起来有点过分 - 表单只是简单地进行数据收集,并且真的不需要与主表单进行任何通信,至少,这是我从这里收集的内容excellent tutorial

  

我在wxPython邮件列表或其IRC频道上看到了关于帧之间通信的一些问题,而且大多数时候开发人员需要的是PubSub模块。发布者/订阅者模型是一种向一个或多个侦听器发送消息的方法。

所有这些看起来都比我需要的要多,除非我误解了教程的作者在两个框架之间进行通信的含义&#39;。

我想我要问的是:同一个应用程序的代码可以存在于几个.py文件中,其中每个表单都有自己的.py文件,由绑定方法调用,以进行排序取而代之:

def dodoInterv(self, event):
    frm = frmIntervw(None, -1, "Post-Discharge Interview")
    frm.Show()

会改为调用(导入?)a .py。 我在这里开了一罐蠕虫吗?

2 个答案:

答案 0 :(得分:0)

对于具有休闲编程背景的人来说,这确实是一个问题。我帮助很多的是通过wxPython wiki中的ModelViewController tutorial。即使您同意使用MVC模式,也很难在不知道术语的情况下理解谈话的内容。

此示例以清晰的方式向您展示MVC模式的哪个部分以及如何使用python / wxPython编写它。

对于您的示例:您将在其自己的对象中填充属于数据检索(sqlite)的所有内容。现在是棘手的部分:如何告诉wxPython对象如何处理模型或如何让模型为他们所知?

输入控制器:假设您要输入查询参数,执行查询并显示结果:

  • 在您的视图部分(将对应于审核框架的GUI部分)输入参数
  • 从控制器绑定到视图部分(例如,单击“查询”时)
  • 使用控制器中的方法作为绑定方法的目标
  • 在控制器方法中执行查询(大致对应于您的doConnect)
  • 在查询控制器方法的末尾使用查询结果更新视图

MVC示例是一个文件,但是如果你将事物分开,你可以放置例如查看单独的.py文件并导入它。 View甚至不需要知道sqlite /模型。模型和视图之间的连接由控制器完成,控制器需要知道这两个对象。

编辑:回答你的原始问题:没有必要使用pubsub,在你相当简单的例子中,你可以使用回调。

HTH

答案 1 :(得分:0)

虽然PyPubSub教程中的示例可能看起来毫无意义,但它只是展示了如何使用该模块。当您需要处理独立于主线程运行的多个线程时,PyPubSub会派上用场。确实如此,至少根据我的经验,可以通过将一个帧的引用传递给另一个帧来克服对PyPubSub的任何需求。

至于你的问题,是的,你可以在几个模块上轻松编写单个应用程序的代码。只需将这些模块导入您需要的模块即可。人们总是这样做,否则就不可能将整个代码写在一个py文件中。

对于您提供的代码,您可以在不同的文件中编写类的代码,只需将类导入主.py文件。

比如说audFrame是在单独的frame.py文件中定义的。您可以将main.py文件的代码更改为以下内容:

import frame

class AuditApp(wx.App):
  def OnInit(self):
    self.aframe = frame.audFrame(None, -1, "Audits Manager")
    self.aframe.Show(True)
    self.SetTopWindow(self.aframe)  # has to be *after* the Show()
    return True

def main():
  app = AuditApp(0)
  app.MainLoop()

if __name__ == '__main__':
  main()