Передача значений между формами с помощью npyscreen
Я пытаюсь создать простое приложение npyscreen curses в python, которое запрашивает ввод данных пользователем на одном экране, а затем проверяет его для пользователя на другом экране.
В основном, это попытка понять, как значения хранятся и извлекаются из 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()
3 ответа
Я не нашел простой способ прямой передачи переменных между формами. Однако вы можете обойти это, используя переменные, которые имеют глобальную область видимости среди форм.
Класс приложения NPSAppManaged выполняется полностью инкапсулированным, поэтому, если вы попытаетесь объявить глобальные переменные в верхней части файла Python, формы внутри не будут иметь доступа к ним. Вместо этого объявите переменные внутри класса приложения NPSAppManaged перед методом onStart, как показано ниже.
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.[Имя переменной]" следующим образом:
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 во время создания метода из глобальных переменных класса приложения.
Один из способов сделать это - использовать getForm перед switchForm для передачи значений. Следующее работает для меня, используя 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()
Присвойте значения (включая значение, возвращаемое addForm) для self.whither. Так что если вы делаете
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
У меня были те же проблемы во время разработки, так как документация не очень подробно о передаче значений между формами.
Я добавил несколько модификаций, первая менялась Form
в ActionForm
в форме подтверждения, чтобы иметь доступ к кнопкам ОК и Отмена. Во-вторых, значения в форме подтверждения не должны редактироваться, так как это подтверждение. Вы можете нажать "Отмена" для редактирования в предыдущей форме. Последний передавал первый элемент списка отдела, а не значение - это был бы просто индекс списка. Надеюсь, это немного поможет.
#!/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()