【问题标题】:Passing values between forms with npyscreen使用 npyscreen 在表单之间传递值
【发布时间】:2015-12-19 01:07:20
【问题描述】:

我正在尝试在 python 中创建一个简单的npyscreen curses 应用程序,它请求用户在一个屏幕上输入,然后在另一个屏幕上为用户验证它。

大多数情况下,这是为了了解如何从npyscreen 中存储和检索值。我确定我遗漏了一些简单的东西,但我无法在文档中找到(或理解?)答案。

下面的示例代码无法正确传递值:

#!/usr/bin/env python3.5

import npyscreen as np

class EmployeeForm(np.Form):
    def afterEditing(self):
        self.parentApp.switchForm('CONFIRMFM')

    def create(self):
        self.myName = self.add(np.TitleText, name='Name')
        self.myDepartment = self.add(np.TitleSelectOne, scroll_exit=True, max_height=3, name='Department', values = ['Department 1', 'Department 2', 'Department 3'])
        self.myDate = self.add(np.TitleDateCombo, name='Date Employed')

class EmployeeConfirmForm(np.Form):
    def afterEditing(self):
        self.parentApp.setNextForm(None)

    def create(self):
        self.value = None
        self.wgName   = self.add(np.TitleText, name = "Name:",)
        self.wgDept = self.add(np.TitleText, name = "Dept:")
        self.wgEmp      = self.add(np.TitleText, name = "Employed:")

    def beforeEditing(self):
        if self.value:
            self.name = "Is this correct?"
            self.wgName.value   = self.myName.value
            self.wgDept.value = self.myDepartment.value
            self.wgEmp.value      = self.myDate.value

    def on_cancel(self):
        self.parentApp.switchFormPrevious()


class myApp(np.NPSAppManaged):
    def onStart(self):
        self.addForm('MAIN', EmployeeForm, name='Employee Entry')
        self.addForm('CONFIRMFM', EmployeeConfirmForm, name='Employee Confirmation')

if __name__ == '__main__':
    TestApp = myApp().run()

【问题讨论】:

    标签: python-curses


    【解决方案1】:

    我还没有找到一种直接在表单之间传递变量的简单方法。但是,您可以通过使用在表单中具有全局范围的变量来解决此问题。

    NPSAppManaged 应用程序类完全封装运行,因此如果您尝试在 Python 文件的顶部声明全局变量,其中的表单将无法访问它们。而是在onStart 方法之前声明NPSAppManaged 应用程序类中的变量,如下所示。

    class myApp(np.NPSAppManaged):
    
        # declare variables here that have global scope to all your forms
        myName, myDepartment, myDate = None, None, None
    
        def onStart(self):
            self.addForm('MAIN', EmployeeForm, name='Employee Entry')
            self.addForm('CONFIRMFM', EmployeeConfirmForm, name='Employee Confirmation')
    
    if __name__ == '__main__':
        TestApp = myApp().run()
    

    然后您可以使用self.parentApp.[variable name] 访问这些变量,如下所示:

    class EmployeeConfirmForm(np.Form):
        def afterEditing(self):
            self.parentApp.setNextForm(None)
    
        def create(self):
            self.add(np.FixedText, value = "Is this correct?")
            self.wgName = self.add(np.TitleText, name = "Name:", value = self.parentApp.myName)
            self.wgDept = self.add(np.TitleText, name = "Dept:", value = self.parentApp.myDepartment)
            self.wgEmp = self.add(np.TitleText, name = "Employed:", value = self.parentApp.myDate)
    
        def on_cancel(self):
            self.parentApp.switchFormPrevious()
    

    注意:您不需要有单独的beforeEditing 方法,因为在create 方法期间,应用程序类全局变量中的值将直接加载到EmployeeConfirmForm

    【讨论】:

      【解决方案2】:

      一种方法是在 switchForm 之前使用 getForm 来传递值。以下适用于我使用 python2 传递名称。传递其他值应该类似。我自己也在学习这一点,但如果您还有其他问题,请发表评论。

      import npyscreen as np
      
      class EmployeeForm(np.ActionForm):
          def create(self):
              self.myName = self.add(np.TitleText, name='Name')
              self.myDepartment = self.add(np.TitleSelectOne, scroll_exit=True, max_height=3, name='Department', values = ['Department 1', 'Department 2', 'Department 3'])
              self.myDate = self.add(np.TitleDateCombo, name='Date Employed')
      
          def afterEditing(self):
              self.parentApp.getForm('CONFIRMFM').wgName.value = self.myName.value
              self.parentApp.switchForm('CONFIRMFM')
      
      class EmployeeConfirmForm(np.Form):
          def afterEditing(self):
              self.parentApp.setNextForm(None)
      
          def create(self):
              self.value = None
              self.wgName  = self.add(np.TitleFixedText, name = "Name:",)
              self.wgDept = self.add(np.TitleText, name = "Dept:")
              self.wgEmp      = self.add(np.TitleText, name = "Employed:")
      
          def on_cancel(self):
              self.parentApp.switchFormPrevious()
      
      class myApp(np.NPSAppManaged):
          def onStart(self):
              self.addForm('MAIN', EmployeeForm, name='Employee Entry')
              self.addForm('CONFIRMFM', EmployeeConfirmForm, name='Employee Confirmation')
      
      if __name__ == '__main__':
          TestApp = myApp().run()
      

      【讨论】:

        【解决方案3】:

        我在开发过程中遇到了同样的问题,因为文档对在表单之间传递值不是很详细。

        我添加了一些修改,第一个是在确认表单中将Form 更改为ActionForm 以访问okcancel 按钮。其次,确认表单上的值不应该是可编辑的,因为这是一个确认。您可以按取消在以前的表单上进行编辑。最后一个是传递部门列表的第一个元素而不是值 - 它只是一个列表索引。希望对大家有所帮助。

        #!/usr/bin/env python3.5
        
        import npyscreen as np
        
        
        class EmployeeForm(np.Form):
        
            def create(self):
                self.myName = self.add(np.TitleText, name='Name')
                self.myDepartment = self.add(np.TitleSelectOne, scroll_exit=True, max_height=3, name='Department', values = ['Department 1', 'Department 2', 'Department 3'])
                self.myDate = self.add(np.TitleDateCombo, name='Date Employed')
        
            def afterEditing(self):
                self.parentApp.switchForm('CONFIRMFM')
                self.parentApp.getForm('CONFIRMFM').wgName.value = self.myName.value
                self.parentApp.getForm('CONFIRMFM').wgDept.value = self.myDepartment.values[0]
                self.parentApp.getForm('CONFIRMFM').wgEmp.value = self.myDate.value
        
        
        class EmployeeConfirmForm(np.ActionForm):
        
            def create(self):
                self.add(np.FixedText, value="Is this correct?", editable=False)
                self.wgName = self.add(np.TitleText, name = "Name:", editable=False)
                self.wgDept = self.add(np.TitleText, name = "Dept:", editable=False)
                self.wgEmp = self.add(np.TitleText, name = "Employed:", editable=False)
        
            def on_ok(self):
                self.parentApp.setNextForm(None)
        
            def on_cancel(self):
                self.parentApp.switchFormPrevious()
        
        
        class myApp(np.NPSAppManaged):
        
            def onStart(self):
                self.addForm('MAIN', EmployeeForm, name='Employee Entry')
                self.addForm('CONFIRMFM', EmployeeConfirmForm, name='Employee Confirmation')
        
        if __name__ == '__main__':
            TestApp = myApp().run()
        

        【讨论】:

          【解决方案4】:

          给 self.whatever 赋值(包括 addForm 返回的值)。 所以如果你这样做了

          self.myAppValue = 2
          self.mainForm = self.addForm('MAIN', MainForm, ...)
          self.form2 = self.addForm('FORM2', Form2, ...)
          

          你可以以任何形式使用它们

          self.parentApp.myAppValue
          self.parentApp.mainForm.main_form_widget.main_form_value
          

          而在 myApp() 中你可以这样做

          self.mainForm.main_form_widget.main_form_value
          

          【讨论】:

            猜你喜欢
            • 2017-09-21
            • 1970-01-01
            • 2011-03-05
            • 2012-10-10
            • 1970-01-01
            • 2014-01-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多