示例#1
0
    def __init__(self, debug=False, storage=None, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        self.storageDirectory = storage
        self.title('Questionnaire Language (QL)')
        self.buildWidgets()

        self.parser = Parser(debug=debug)

        # To keep output in order
        self.widgets = OrderedDict()
        self.answers = OrderedDict()

        self.questions = []
        self.branches = []
    def setUp(self):
        self.duplicateQuestions = DuplicateQuestions()
        self.undefinedQuestions = UndefinedQuestions()
        self.nonBoolean = NonBooleanTypes()
        self.nonOperand = NonOperandTypes()
        self.nonExpressions = NonExpressions()

        self.parser = Parser()
        self.checker = TypeChecker()

        self.checker.register(self.duplicateQuestions)
        self.checker.register(self.undefinedQuestions)
        self.checker.register(self.nonBoolean)
        self.checker.register(self.nonOperand)
        self.checker.register(self.nonExpressions)
示例#3
0
文件: main.py 项目: guyromb/many-ql
    def __init__(self, debug=False, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.title('Questionnaire Language (QL)')

        self.parser = Parser(debug=debug)

        self.buildWidgets()
        self.currentWidget = None

        self.answers = {}
示例#4
0
class EvaluationTests(unittest.TestCase):
    def setUp(self):
        self.parser = Parser()

    def testTrueExpressions(self):
        with open(lib.formFilePath("trueExpressions.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

        gui = GUI()
        gui._buildForm(parsed)

        # Fire 'change' event
        gui.onChange()

        for node in gui.branches:
            if not node.evaluate(gui.answers):
                print node
                print node.evaluate(gui.answers)
                print gui.answers
                print "-----"

            self.assertEqual(True, bool(node.evaluate(gui.answers)))


    def testFalseExpressions(self):
        with open(lib.formFilePath("falseExpressions.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

        gui = GUI()
        gui._buildForm(parsed)

        # Fire 'change' event
        gui.onChange()

        for node in gui.branches:
            if node.evaluate(gui.answers):
                print node
                print node.evaluate(gui.answers)
                print gui.answers
                print "-----"

            self.assertEqual(False, bool(node.evaluate(gui.answers)))
class EvaluationTests(unittest.TestCase):
    def setUp(self):
        self.parser = Parser()

    def testTrueExpressions(self):
        with open(lib.formFilePath("trueExpressions.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

        gui = GUI()
        gui._buildForm(parsed)

        # Fire 'change' event
        gui.onChange()

        for node in gui.branches:
            if not node.evaluate(gui.answers):
                print node
                print node.evaluate(gui.answers)
                print gui.answers
                print "-----"

            self.assertEqual(True, bool(node.evaluate(gui.answers)))

    def testFalseExpressions(self):
        with open(lib.formFilePath("falseExpressions.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

        gui = GUI()
        gui._buildForm(parsed)

        # Fire 'change' event
        gui.onChange()

        for node in gui.branches:
            if node.evaluate(gui.answers):
                print node
                print node.evaluate(gui.answers)
                print gui.answers
                print "-----"

            self.assertEqual(False, bool(node.evaluate(gui.answers)))
示例#6
0
    def setUp(self):
        self.duplicateQuestions = DuplicateQuestions()
        self.undefinedQuestions = UndefinedQuestions()
        self.nonBoolean         = NonBooleanTypes()
        self.nonOperand         = NonOperandTypes()
        self.nonExpressions     = NonExpressions()

        self.parser = Parser()
        self.checker = TypeChecker()

        self.checker.register(self.duplicateQuestions)
        self.checker.register(self.undefinedQuestions)
        self.checker.register(self.nonBoolean)
        self.checker.register(self.nonOperand)
        self.checker.register(self.nonExpressions)
示例#7
0
    def __init__(self, debug=False, storage=None, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        self.storageDirectory = storage
        self.title('Questionnaire Language (QL)')
        self.buildWidgets()

        self.parser = Parser(debug=debug)

        # To keep output in order
        self.widgets = OrderedDict()
        self.answers = OrderedDict()

        self.questions = []
        self.branches  = []
示例#8
0
class ParseTests(unittest.TestCase):
    def setUp(self):
        self.parser = Parser()

    def testEmptyFile(self):
        formText = "   \t   \r\n   \n \n "
        parsed = self.parser.parse(formText)

        self.assertEquals(parsed, [])

    def testEmptyForm(self):
        formText = "form taxOfficeExample {}"
        parsed = self.parser.parse(formText)

        self.assertEquals(parsed.__class__.__name__, "Form")
        self.assertEquals(len(parsed.block), 0)

    def testNonClosingForm(self):
        formText = "form taxOfficeExample {"
        self.assertRaises(ParseError, self.parser.parse, formText)

    # Parser does not accept multiple forms in single file
    def testMultipleForms(self):
        formText = "form taxOfficeExample {} form taxExampleB {}"
        self.assertRaises(ParseError, self.parser.parse, formText)

    def testSimpleForm(self):
        with open(lib.formFilePath("simple.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

            self.assertEquals(parsed.__class__.__name__, "Form")
            self.assertEquals(len(parsed.block), 4)

            file.close()

    def testSkipComments(self):
        with open(lib.formFilePath("comments.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

            self.assertEquals(parsed.__class__.__name__, "Form")
            self.assertEquals(len(parsed.block), 1)

            file.close()

    def testTypes(self):
        with open(lib.formFilePath("types.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

            self.assertEquals(parsed.__class__.__name__, "Form")
            self.assertEquals(len(parsed.block), 5)

            file.close()


    def testUndefinedType(self):
        with open(lib.formFilePath("undefinedType.txt"), "r") as file:
            self.assertRaises(ParseError, self.parser.parse, file.read())

            file.close()


    def testIfBlocks(self):
        with open(lib.formFilePath("simpleIf.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

            self.assertEquals(parsed.__class__.__name__, "Form")
            self.assertEquals(len(parsed.block), 2)

            file.close()

    def testIfElse(self):
        with open(lib.formFilePath("ifElse.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

            self.assertEquals(parsed.__class__.__name__, "Form")
            self.assertEquals(len(parsed.block), 1)

            file.close()

    def testNestedIfBlocks(self):
        with open(lib.formFilePath("nestedIf.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

            self.assertEquals(parsed.__class__.__name__, "Form")
            self.assertEquals(len(parsed.block), 1)

            self.assertEquals(parsed.block[0].__class__.__name__, "Branch")
            self.assertEquals(len(parsed.block[0].ifChildren), 2)

            file.close()


    def testExpressions(self):
        with open(lib.formFilePath("expressions.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

            self.assertEquals(parsed.__class__.__name__, "Form")
            self.assertEquals(len(parsed.block), 13)

            file.close()
示例#9
0
 def setUp(self):
     self.parser = Parser()
 def setUp(self):
     self.parser = Parser()
示例#11
0
class TypecheckingTests(unittest.TestCase):
    def setUp(self):
        self.duplicateQuestions = DuplicateQuestions()
        self.undefinedQuestions = UndefinedQuestions()
        self.nonBoolean         = NonBooleanTypes()
        self.nonOperand         = NonOperandTypes()
        self.nonExpressions     = NonExpressions()

        self.parser = Parser()
        self.checker = TypeChecker()

        self.checker.register(self.duplicateQuestions)
        self.checker.register(self.undefinedQuestions)
        self.checker.register(self.nonBoolean)
        self.checker.register(self.nonOperand)
        self.checker.register(self.nonExpressions)


    def testDuplicateQuestions(self):
        with open(lib.formFilePath("duplicateQuestions.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

        self.checker.checkAST(parsed)

        self.assertEqual(len(self.duplicateQuestions.errors), 1)
        self.assertEqual(len(self.undefinedQuestions.errors), 0)

    def testDuplicateQuestionsNested(self):
        with open(lib.formFilePath("duplicateQuestionsNested.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

        self.checker.checkAST(parsed)

        self.assertEqual(len(self.duplicateQuestions.errors), 1)

    def testUndefinedQuestions(self):
        with open(lib.formFilePath("undefinedQuestions.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

        self.checker.checkAST(parsed)

        self.assertEqual(len(self.duplicateQuestions.errors), 0)
        self.assertEqual(len(self.undefinedQuestions.errors), 1)


    def testUndefinedQuestionsNested(self):
        with open(lib.formFilePath("undefinedQuestionsNested.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

        self.checker.checkAST(parsed)

        self.assertEqual(len(self.duplicateQuestions.errors), 0)
        self.assertEqual(len(self.undefinedQuestions.errors), 1)


    def testIncompatibleTypes(self):
        with open(lib.formFilePath("expressionTypes.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

        self.checker.checkAST(parsed)

        self.assertEqual(len(self.duplicateQuestions.errors), 0)
        self.assertEqual(len(self.undefinedQuestions.errors), 0)
        self.assertEqual(len(self.nonExpressions.errors), 1)

    def testIncompatibleNestedTypes(self):
        with open(lib.formFilePath("expressionTypesNested.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

        self.checker.checkAST(parsed)

        self.assertEqual(len(self.duplicateQuestions.errors), 0)
        self.assertEqual(len(self.undefinedQuestions.errors), 0)
        self.assertEqual(len(self.nonExpressions.errors), 4)
class TypecheckingTests(unittest.TestCase):
    def setUp(self):
        self.duplicateQuestions = DuplicateQuestions()
        self.undefinedQuestions = UndefinedQuestions()
        self.nonBoolean = NonBooleanTypes()
        self.nonOperand = NonOperandTypes()
        self.nonExpressions = NonExpressions()

        self.parser = Parser()
        self.checker = TypeChecker()

        self.checker.register(self.duplicateQuestions)
        self.checker.register(self.undefinedQuestions)
        self.checker.register(self.nonBoolean)
        self.checker.register(self.nonOperand)
        self.checker.register(self.nonExpressions)

    def testDuplicateQuestions(self):
        with open(lib.formFilePath("duplicateQuestions.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

        self.checker.checkAST(parsed)

        self.assertEqual(len(self.duplicateQuestions.errors), 1)
        self.assertEqual(len(self.undefinedQuestions.errors), 0)

    def testDuplicateQuestionsNested(self):
        with open(lib.formFilePath("duplicateQuestionsNested.txt"),
                  "r") as file:
            parsed = self.parser.parse(file.read())

        self.checker.checkAST(parsed)

        self.assertEqual(len(self.duplicateQuestions.errors), 1)

    def testUndefinedQuestions(self):
        with open(lib.formFilePath("undefinedQuestions.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

        self.checker.checkAST(parsed)

        self.assertEqual(len(self.duplicateQuestions.errors), 0)
        self.assertEqual(len(self.undefinedQuestions.errors), 1)

    def testUndefinedQuestionsNested(self):
        with open(lib.formFilePath("undefinedQuestionsNested.txt"),
                  "r") as file:
            parsed = self.parser.parse(file.read())

        self.checker.checkAST(parsed)

        self.assertEqual(len(self.duplicateQuestions.errors), 0)
        self.assertEqual(len(self.undefinedQuestions.errors), 1)

    def testIncompatibleTypes(self):
        with open(lib.formFilePath("expressionTypes.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

        self.checker.checkAST(parsed)

        self.assertEqual(len(self.duplicateQuestions.errors), 0)
        self.assertEqual(len(self.undefinedQuestions.errors), 0)
        self.assertEqual(len(self.nonExpressions.errors), 1)

    def testIncompatibleNestedTypes(self):
        with open(lib.formFilePath("expressionTypesNested.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

        self.checker.checkAST(parsed)

        self.assertEqual(len(self.duplicateQuestions.errors), 0)
        self.assertEqual(len(self.undefinedQuestions.errors), 0)
        self.assertEqual(len(self.nonExpressions.errors), 4)
示例#13
0
class GUI(tk.Tk):
    def __init__(self, debug=False, storage=None, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        self.storageDirectory = storage
        self.title('Questionnaire Language (QL)')
        self.buildWidgets()

        self.parser = Parser(debug=debug)

        # To keep output in order
        self.widgets = OrderedDict()
        self.answers = OrderedDict()

        self.questions = []
        self.branches  = []


    def run(self):
        self.mainloop()


    def buildWidgets(self):
        self.frame = tk.Frame()
        self.frame.pack(
            side="top",
            fill="both",
            expand=True,
            pady=10,
            padx=10
        )

        self.buttonBarRight = tk.Frame(padx=10, pady=10)
        self.buttonBarRight.pack(side="right", anchor="e")

        self.buttonBarLeft = tk.Frame(pady=10)
        self.buttonBarLeft.pack(side="left", anchor="w")

        self.fileSelect = myTk.FileDialog(
            master=self.frame,
            onFileSelected=self._parseContents
        )

        self.saveButton = tk.Button(
            self.buttonBarRight,
            text="Save form",
            command=self._save,
            bg='#CBE86B',
            cursor="hand2"
        )

        self.resetButton = tk.Button(
            self.buttonBarLeft,
            text="Reset",
            command=self._reset
        )

        self.cancelButton = tk.Button(
            self.buttonBarLeft,
            text="Cancel",
            command=self._cancel
        )


    def _parseContents(self, contents=""):
        self._parsed = self.parser.parse(contents)

        if self.parser.hasErrors:
            errors = self.parser.getErrorMessages()
            tkMessageBox.showerror(
                "Parsing file",
                "\n\n".join(errors)
            )
            return None

        self._typeChecking(self._parsed)


    def _typeChecking(self, parsed):
        checker = QLTypeChecker(parsed)

        if checker.hasErrors:
            errors = checker.getErrorMessages()
            tkMessageBox.showerror(
                "Typechecking",
                "\n\n".join(errors)
            )
            return None

        self._buildForm(parsed)


    def _buildForm(self, parsed):
        self.widgets = OrderedDict()
        self.answers = OrderedDict()
        self.questions = parsed.findAll("Question")
        self.branches  = parsed.findAll("Branch")

        self.fileSelect.hide()
        self.cancelButton.pack(side="left", padx=5)
        self.resetButton.pack(side="right")
        self.saveButton.pack(side="right")

        rowCount = 0
        for node in self.questions:
            try:
                nodeWidget = getattr(Widgets, node.widgetName())(self.frame, node, self.onChange, rowCount)
                self.widgets[node] = nodeWidget
                rowCount += nodeWidget.rowCount
            except Exception as err:
                print err

        # Display top-level questions
        for node in parsed.findChildren("Question"):
            self.widgets[node].show()

        self.onChange()


    def onChange(self, event=None):
        for node, widget in self.widgets.iteritems():
            widget.setValid()

            if widget.visible:
                self.answers[node] = widget.value()

        # Compute & display readOnly values
        for widget in self.widgets.values():
            if widget.isReadOnly():
                widget.setValue(self.answers)

        # Evaluate branches and display children-widgets accordingly
        for node in self.branches:
            if node.evaluate(self.answers):
                toShow = node.ifChildren
                toHide = node.elseChildren
            else:
                toShow = node.elseChildren
                toHide = node.ifChildren

            for child in toShow:
                if child in self.widgets:
                    self.widgets[child].show()

            for child in toHide:
                if child in self.widgets:
                    self.widgets[child].hide()


    def _save(self):
        userId   = uuid.uuid4()
        userFile = "%s/%s.txt" % (self.storageDirectory, userId)

        with open(userFile,'w') as f:
            for question, answer in self.answers.iteritems():
                f.write(question.labelText())
                f.write("\n")
                f.write("Answer: %s" % answer)
                f.write("\n-------------------\n")

            f.close()

        self._cancel()

    def _cancel(self):
        # Remove current widgets
        for node, widget in self.widgets.iteritems():
            widget.tearDown()

        self.saveButton.pack_forget()
        self.resetButton.pack_forget()
        self.cancelButton.pack_forget()

        self.fileSelect.show()


    def _reset(self):
        # Remove current form widgets
        for node, widget in self.widgets.iteritems():
            widget.tearDown()

        # Rebuild form
        self._buildForm(self._parsed)
示例#14
0
class ParseTests(unittest.TestCase):
    def setUp(self):
        self.parser = Parser()

    def testEmptyFile(self):
        formText = "   \t   \r\n   \n \n "
        parsed = self.parser.parse(formText)

        self.assertEquals(parsed, None)

    def testEmptyForm(self):
        formText = "form taxOfficeExample {}"
        parsed = self.parser.parse(formText)

        self.assertEquals(parsed.__class__.__name__, "Form")
        self.assertEquals(len(parsed.block), 0)

    def testNonClosingForm(self):
        formText = "form taxOfficeExample {"
        parsed = self.parser.parse(formText)

        self.assertEquals(True, self.parser.hasErrors)

    # Parser does not accept multiple forms in single file
    def testMultipleForms(self):
        formText = "form taxOfficeExample {} form taxExampleB {}"
        parsed = self.parser.parse(formText)

        self.assertEquals(True, self.parser.hasErrors)

    def testSimpleForm(self):
        with open(lib.formFilePath("simple.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

            self.assertEquals(parsed.__class__.__name__, "Form")
            self.assertEquals(len(parsed.block), 4)

            file.close()

    def testSkipComments(self):
        with open(lib.formFilePath("comments.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

            self.assertEquals(parsed.__class__.__name__, "Form")
            self.assertEquals(len(parsed.block), 1)

            file.close()

    def testTypes(self):
        with open(lib.formFilePath("types.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

            self.assertEquals(parsed.__class__.__name__, "Form")
            self.assertEquals(len(parsed.block), 5)

            file.close()

    def testUndefinedType(self):
        with open(lib.formFilePath("undefinedType.txt"), "r") as file:
            parsed = self.parser.parse(file.read())
            self.assertEquals(True, self.parser.hasErrors)

            file.close()

    def testIfBlocks(self):
        with open(lib.formFilePath("simpleIf.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

            self.assertEquals(parsed.__class__.__name__, "Form")
            self.assertEquals(len(parsed.block), 2)

            file.close()

    def testIfElse(self):
        with open(lib.formFilePath("ifElse.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

            self.assertEquals(parsed.__class__.__name__, "Form")
            self.assertEquals(len(parsed.block), 1)

            file.close()

    def testNestedIfBlocks(self):
        with open(lib.formFilePath("nestedIf.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

            self.assertEquals(parsed.__class__.__name__, "Form")
            self.assertEquals(len(parsed.block), 1)

            self.assertEquals(parsed.block[0].__class__.__name__, "Branch")
            self.assertEquals(len(parsed.block[0].ifChildren), 2)

            file.close()

    def testExpressions(self):
        with open(lib.formFilePath("expressions.txt"), "r") as file:
            parsed = self.parser.parse(file.read())

            self.assertEquals(parsed.__class__.__name__, "Form")
            self.assertEquals(len(parsed.block), 13)

            file.close()
示例#15
0
class GUI(tk.Tk):
    def __init__(self, debug=False, storage=None, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        self.storageDirectory = storage
        self.title('Questionnaire Language (QL)')
        self.buildWidgets()

        self.parser = Parser(debug=debug)

        # To keep output in order
        self.widgets = OrderedDict()
        self.answers = OrderedDict()

        self.questions = []
        self.branches = []

    def run(self):
        self.mainloop()

    def buildWidgets(self):
        self.frame = tk.Frame()
        self.frame.pack(side="top", fill="both", expand=True, pady=10, padx=10)

        self.buttonBarRight = tk.Frame(padx=10, pady=10)
        self.buttonBarRight.pack(side="right", anchor="e")

        self.buttonBarLeft = tk.Frame(pady=10)
        self.buttonBarLeft.pack(side="left", anchor="w")

        self.fileSelect = myTk.FileDialog(master=self.frame,
                                          onFileSelected=self._parseContents)

        self.saveButton = tk.Button(self.buttonBarRight,
                                    text="Save form",
                                    command=self._save,
                                    bg='#CBE86B',
                                    cursor="hand2")

        self.resetButton = tk.Button(self.buttonBarLeft,
                                     text="Reset",
                                     command=self._reset)

        self.cancelButton = tk.Button(self.buttonBarLeft,
                                      text="Cancel",
                                      command=self._cancel)

    def _parseContents(self, contents=""):
        self._parsed = self.parser.parse(contents)

        if self.parser.hasErrors:
            errors = self.parser.getErrorMessages()
            tkMessageBox.showerror("Parsing file", "\n\n".join(errors))
            return None

        self._typeChecking(self._parsed)

    def _typeChecking(self, parsed):
        checker = QLTypeChecker(parsed)

        if checker.hasErrors:
            errors = checker.getErrorMessages()
            tkMessageBox.showerror("Typechecking", "\n\n".join(errors))
            return None

        self._buildForm(parsed)

    def _buildForm(self, parsed):
        self.widgets = OrderedDict()
        self.answers = OrderedDict()
        self.questions = parsed.findAll("Question")
        self.branches = parsed.findAll("Branch")

        self.fileSelect.hide()
        self.cancelButton.pack(side="left", padx=5)
        self.resetButton.pack(side="right")
        self.saveButton.pack(side="right")

        rowCount = 0
        for node in self.questions:
            try:
                nodeWidget = getattr(Widgets,
                                     node.widgetName())(self.frame, node,
                                                        self.onChange,
                                                        rowCount)
                self.widgets[node] = nodeWidget
                rowCount += nodeWidget.rowCount
            except Exception as err:
                print err

        # Display top-level questions
        for node in parsed.findChildren("Question"):
            self.widgets[node].show()

        self.onChange()

    def onChange(self, event=None):
        for node, widget in self.widgets.iteritems():
            widget.setValid()

            if widget.visible:
                self.answers[node] = widget.value()

        # Compute & display readOnly values
        for widget in self.widgets.values():
            if widget.isReadOnly():
                widget.setValue(self.answers)

        # Evaluate branches and display children-widgets accordingly
        for node in self.branches:
            if node.evaluate(self.answers):
                toShow = node.ifChildren
                toHide = node.elseChildren
            else:
                toShow = node.elseChildren
                toHide = node.ifChildren

            for child in toShow:
                if child in self.widgets:
                    self.widgets[child].show()

            for child in toHide:
                if child in self.widgets:
                    self.widgets[child].hide()

    def _save(self):
        userId = uuid.uuid4()
        userFile = "%s/%s.txt" % (self.storageDirectory, userId)

        with open(userFile, 'w') as f:
            for question, answer in self.answers.iteritems():
                f.write(question.labelText())
                f.write("\n")
                f.write("Answer: %s" % answer)
                f.write("\n-------------------\n")

            f.close()

        self._cancel()

    def _cancel(self):
        # Remove current widgets
        for node, widget in self.widgets.iteritems():
            widget.tearDown()

        self.saveButton.pack_forget()
        self.resetButton.pack_forget()
        self.cancelButton.pack_forget()

        self.fileSelect.show()

    def _reset(self):
        # Remove current form widgets
        for node, widget in self.widgets.iteritems():
            widget.tearDown()

        # Rebuild form
        self._buildForm(self._parsed)
示例#16
0
文件: main.py 项目: guyromb/many-ql
class GUI(tk.Tk):
    def __init__(self, debug=False, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.title('Questionnaire Language (QL)')

        self.parser = Parser(debug=debug)

        self.buildWidgets()
        self.currentWidget = None

        self.answers = {}

    def run(self):
        self.mainloop()

    def buildWidgets(self):
        self.frame = tk.Frame()
        self.frame.pack(side="top", fill="both", expand=True)
        self.frame.grid_columnconfigure(0, weight=1)

        self.fileSelect = tk.Button(text="Select file", command=self.loadFile)
        self.fileSelect.pack()

    def loadFile(self):
        try:
            with askopenfile(mode='r') as file:
                self._parseContents(file.read())
                file.close()
        except AttributeError:
            # User cancels file selection
            pass
        except Exception as p:
            print p

    def _parseContents(self, contents="", callback=None):
        try:
            parsed = self.parser.parse(contents)
        except Exception as parseError:
            return tkMessageBox.showerror(
                "Parsing file",
                "Cannot parse file `%s`\n\n%s" % (self.fileName, parseError)
            )

        self._typeCheck(parsed)

    def _typeCheck(self, parsed):
        checker = QLTypeChecker(parsed)

        if checker.hasErrors:
            errors = checker.getErrorMessages()

            tkMessageBox.showerror(
                "Typechecking",
                "\n\n".join(errors)
            )

        else:
            self._buildForm(parsed)

    def _buildForm(self, parsed):
        # Hide file select
        self.fileSelect.pack_forget()

        # Display buttons for progress
        self.prevButton = tk.Button(text="Back", command=self._prev)
        self.prevButton.pack()

        self.nextButton = tk.Button(text="Next question", command=self._next)
        self.nextButton.pack()

        # Start initial question
        self.builder = FormBuilder(self.frame, parsed)
        self._next()


    def _prev(self):
        widget = self.builder.prevQuestion()
        self._displayQuestion(widget)

    def _next(self):
        if self.currentWidget:
            val = self.currentWidget.value()
            self.answers.update(val)

            self.builder.availableAnswers(self.answers)

        try:
            widget = self.builder.nextQuestion()
            self._displayQuestion(widget)

        except ValueError as err:
            tkMessageBox.showerror(
                "Input error",
                "Your given answer is not a number"
            )


    def _displayQuestion(self, questionWidget=None):
        # Remove "previous" visible question
        if self.currentWidget:
            self.currentWidget.tearDown()

        if questionWidget:
            self.currentWidget = questionWidget
        else:
            self._saveAnswers()
            self._reset()

    def _saveAnswers(self):
        if self.answers:
            ID = uuid.uuid1()
            # TODO Store/persist answers in database

    # i.e. start state of file-select
    def _reset(self):
        self.fileSelect.pack()

        self.prevButton.pack_forget()
        self.nextButton.pack_forget()