Python 选择题测验或考试生成器

Python 选择题测验或考试生成器,python,python-3.x,pyqt,pyqt5,qt-designer,Python,Python 3.x,Pyqt,Pyqt5,Qt Designer,我正在尝试创建一个脚本或应用程序来创建多项选择题测验。它将允许用户输入一个问题,然后给出一个真实的答案和一系列可供选择的答案。用户可以根据自己的意愿多次重复该过程。然后,用户需要输入所创建测验的问题数量。最后,测验将保存为pdf或word文档。所有这些都需要一个用Qt制作的gui。到目前为止,我已经完成了大部分的测试脚本,它工作正常。(仍然需要弄清楚如何在答案前添加a、b、c…并保存到pdf,但这不应该是个问题)。gui也完成了,我认为它应该可以正常工作 问题是我不知道如何将测验脚本与gui连接

我正在尝试创建一个脚本或应用程序来创建多项选择题测验。它将允许用户输入一个问题,然后给出一个真实的答案和一系列可供选择的答案。用户可以根据自己的意愿多次重复该过程。然后,用户需要输入所创建测验的问题数量。最后,测验将保存为pdf或word文档。所有这些都需要一个用Qt制作的gui。到目前为止,我已经完成了大部分的测试脚本,它工作正常。(仍然需要弄清楚如何在答案前添加a、b、c…并保存到pdf,但这不应该是个问题)。gui也完成了,我认为它应该可以正常工作

问题是我不知道如何将测验脚本与gui连接起来。我尝试了很多东西,但都不管用

import json
import random

def quiz_name():
    name = input('Enter the name of the quiz file: ')
    return name

def question_generator():
    question_text = input('Enter a question. When done entering questions type \'stop\': ')
    if question_text.lower() == 'stop':
        return None

    true = input('Enter the correct answer: ')

    answer_dict = []
    while True:
        answer = input('Enter an answer. When done entering questions type \'stop\': ')
        if answer.lower() == 'stop':
            break
        answer_dict.append(answer)         
    qapair = (question_text, true, answer_dict) 

    return qapair



def question_list_builder():
    questions = []
    while True:
        qg_method = question_generator()
        if qg_method is None:
            break
        q = (qg_method[0], qg_method[1],qg_method[2]) 
        questions.append(q)
    return questions

#lista_pitanja = question_list_builder()

#for lp in lista_pitanja:
#    pitanje=lista_pitanja
#    broj =0
#    while broj <len(lista_pitanja[2]):
#        print(broj+1,+': '+)
#        broj+=1

class ObjectEncoder(json.JSONEncoder):
  def default(self, obj):
    return obj.__dict__

if __name__ == '__main__':
    quest = question_list_builder()
    name = quiz_name()
    def JSONWrite(quiz, filepath):
        with open(f'{filepath}.json', 'w') as fp:
            fp.write(quiz)
    print(json.dumps(quest, cls=ObjectEncoder))
#    random.sample(pitanja,4)
    JSONWrite(json.dumps(random.sample(quest,3), cls=ObjectEncoder, indent=4),name)

您的代码存在严重的逻辑、概念和编程问题

首先:即使看起来不是很重要,也不要使用与内置类型太相似的变量名(在您的情况下,
true
True
(以及
False
)是内置的布尔值,使用这样的名称(即使使用不同的大小写)可能会导致可读性问题,并最终导致调试问题。
始终使用清晰且唯一的变量名,在您的情况下,它可能类似于
correctAnswer

第二,在处理UI元素时不要使用while循环。图形界面通常基于一个期望某种类型的交互(来自用户或系统)并等待这种情况发生的。使用while循环(或者,无论如何,任何类型的循环,包括循环的或对函数的递归调用)将阻止接收这些事件的能力,从而使接口无法使用

第三;不能在字符串和连接返回值(通常为
None
)之间使用
if
语句:这是苹果和桔子。 当您执行
someSignal.connect(someSlot)
时,您实际上是在告诉Qt,每当发出
someSignal
时,它都必须调用该
someSlot

想象一下这样的情景:

self.fridge.empty.connect(self.goToMall)
每当冰箱说它是空的时,就会调用
goToMall
。然后,假设你要去度假,你不想让你的冰箱装满:

self.fridge.empty.disconnect(self.goToMall)
正如您所看到的,
connect
不会返回任何有用的字符串比较信息:这就像说“检查我的名字是否等于冰箱空了我就去购物中心的事实”。
注意:
connect()
文档返回一个
Connection
对象,该对象稍后可用于断开连接。在我使用的PyQt(相当旧)版本中,它只返回
None
,但在此期间可能会发生更改。也就是说,无效比较问题仍然存在

第四,不要返回
print()
:它只返回None,这是不必要的

最后,决不为您的程序混合从
pyuic
生成的代码。保持py文件的原样,并按说明将其作为模块导入


现在,重新生成使用Designer创建的
.ui
文件,并在另一个文件中使用类似的内容,该文件将成为主程序脚本:

from PyQt5 import QtWidgets
from ui_form import Ui_Form

# I'm using the third method described in the designer documentation given above, 
# the multiple inheritance approach
class QuestionBuilder(QtWidgets.QWidget, Ui_Form):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.New_Question_btn.clicked.connect(self.question_generator)

        self.questions = []

    def question_generator(self):
        question_text = self.LE_Question.text()
        # I don't really know what you meant by comparing the string with the
        # connection, I'm assuming you didn't want to add the same question twice
        if self.questions and self.questions[-1].lower() == question_text:
        for existing_questions in self.questions:
            if question_text.lower() == existing_questions[0]:
                print('question already exists, ignoring')
                return

        correctAnswer = self.LE_TAnswer.text()

        answers = []
        answers.append(self.LE_Answer.text())
        self.questions.append((question_text, correctAnswer, answers))

        self.LE_Answer.clear()
        self.LE_Question.clear()
        self.LE_TAnswer.clear()

        print(self.questions)

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = QuestionBuilder()
    window.show()
    sys.exit(app.exec_())
请注意,在上面的示例中,我没有执行正确答案检查(也没有检查所有可能的答案,也没有检查与其他按钮相关的功能)

让我告诉您,您的方法存在几个UI问题,这些问题可能会导致难以调试的副作用(通过编程和用户体验),我认为最重要的问题是添加了太多带有不必要功能的按钮(以及不清楚的描述)您必须考虑的问题-不要考虑创建一个让最终用户感到困惑的界面。
当点击“输入T答案”且不存在问题时,您会怎么做?如果您单击“输入答案”,而有效答案字段为空,该怎么办?如果一个答案与另一个答案相似,但有不同的字母,并且其中只有一个是准确的,该怎么办?当某个字段无效时,您如何真正检测并通知用户


我真的认为,在编写实际代码之前,您需要完全重新考虑整个界面,可能需要使用一种动态方式添加答案,并提供一个系统,允许用户选择其中哪一个是正确的答案。

粘贴GUI代码。您可以在GUI中的某个位置进行流程调用以执行脚本(比如单击按钮)或者更好的做法是将脚本设置为类,导入并在gui中使用它。我尝试从脚本中逐个添加函数并将它们与gui连接,但没有成功。我对python的知识有点有限:)
from PyQt5 import QtWidgets
from ui_form import Ui_Form

# I'm using the third method described in the designer documentation given above, 
# the multiple inheritance approach
class QuestionBuilder(QtWidgets.QWidget, Ui_Form):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.New_Question_btn.clicked.connect(self.question_generator)

        self.questions = []

    def question_generator(self):
        question_text = self.LE_Question.text()
        # I don't really know what you meant by comparing the string with the
        # connection, I'm assuming you didn't want to add the same question twice
        if self.questions and self.questions[-1].lower() == question_text:
        for existing_questions in self.questions:
            if question_text.lower() == existing_questions[0]:
                print('question already exists, ignoring')
                return

        correctAnswer = self.LE_TAnswer.text()

        answers = []
        answers.append(self.LE_Answer.text())
        self.questions.append((question_text, correctAnswer, answers))

        self.LE_Answer.clear()
        self.LE_Question.clear()
        self.LE_TAnswer.clear()

        print(self.questions)

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = QuestionBuilder()
    window.show()
    sys.exit(app.exec_())