使用npyscreen在表单之间传递值

时间:2015-12-19 01:07:21

标签: python-curses

我正在尝试在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()

4 个答案:

答案 0 :(得分:4)

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

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

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方法,因为在EmployeeConfirmForm方法期间,值将直接加载到create app类全局变量。

答案 1 :(得分: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()

答案 2 :(得分:1)

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

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

#!/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()

答案 3 :(得分:0)

将值(包括addForm返回的值)分配给self.whatever。 所以,如果你这样做

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