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