疯狂刷题python版 | 使用PySide6自制刷题软件【源码+解析】

疯狂刷题python版 | 使用PySide6自制刷题软件【源码+解析】

    • 一、前言
    • 二、思考
    • 三、软件设计
    • 四、软件实现
      • (一)使用QWebEngineView控件通过JavaScript代码和chrome内核进行数据交互和逻辑控制
      • (二)用户分别通过浏览器 GUI和PySide6 GUI进行操作
      • (三)使用PySide6 GUI获取用户计算机本地资源
    • 五、遇到问题及解决方案
      • (一)如何把excel数据转换成json数据?
      • (二)如何向chrome内核传递带大量json数据参数的JavaScript代码?
      • (三)如何区分不同的题库,同样的题库只保存一份?
      • (四)如何保存来自浏览器GUI的答题数据,同样的答题记录只保存一份,并与对应的题库关联?
    • 六、完整源代码和可执行程序

一、前言

考试作为一种衡量个人知识和技能水平的评估方式,已融入了我们的工作和生活。求学时期,从幼儿园到高中、大学,每个教育阶段都免不了考试;工作前后,考试以笔试、面试等形式频繁出现,并作为企业选拔和晋升的主要依据;生活中,我们的驾驶证,一些行业专业资格,也是通过考试获取。

在此过程中,复习题库成了大家通过考试的重要法宝,但大多数行业、政企提供的复习题库多是word、excel等文档形式,复习起来效率不高,由此催生出了各类刷题网站、软件、手机app等工具。这些工具提供了导入题库、保存历史答题记录、错题本、标记重点、答题分析评估等功能,极大提高了考试的复习效率和通过率。

这里先放放程序运行效果,如下图:
在这里插入图片描述
在这里插入图片描述

二、思考

最近在学习PySide6开发,在学习到QT的QWebEngineView控件时,发现PySide6提供了比较完整的浏览器控件支持,而在2017年博主也使用过HTML+JavaScript+IE浏览器AX控件开发了HTML版的刷题工具,但当时没学Python所以只能在IE浏览器中运行。JavaScript|免费导入题库,考试复习工具,刷题神器,支持导入excel题库

缕一缕思路,如使用PySide6提供的QWebEngineView控件改造原来的刷题程序,基于HTML+JavaScript做界面(第一层)UI,基于PySide6 GUI做控制(第二层)UI,使用Python做算法逻辑开发,就能实现类似electron的能力,使得python开发也能利用HTML+JavaScript+CSS海量的UI界面的资源。

三、软件设计

根据以上思路,对原来写的程序设计进行了调整,得到一下程序实现方式简图,这个图是用Markdown提供的mermaid流程图做的,感觉还是挺厉害的,感觉有时间要好好研究一下Markdown。只要简单写写mermaid脚本,就可生成以下简洁明了的流程图。

程序实现方式
signal
JavaScript
Json
chrome内核
浏览器 GUI
HTML+CSS+JavaScript
PySide6 GUI
python
QWebEngineView控件
题库数据文件
用户

四、软件实现

(一)使用QWebEngineView控件通过JavaScript代码和chrome内核进行数据交互和逻辑控制

runJavaScript()函数可以在QWebEngineView或QWebEnginePage对象上调用,以在 Web页面上执行JavaScript代码。它接受一个字符串参数,该字符串是要执行的JavaScript代码。

在PySide6中可以使用以下Python代码向浏览器发送待执行的JavaScript脚本(带参)。self.webEngineView.page().runJavaScript(js_string, 0, js_callback)中js_string是需要执行的JavaScript脚本,js_callback是回调函数,若浏览器执行代码成功则调用js_callback代码。

    self.js_Button = QPushButton()self.js_Button.setText('运行JS脚本')self.js_Button.clicked.connect(self.run_js)def run_js(self):js_string, ok = QInputDialog.getMultiLineText(self, "请输入JS脚本", "可输入多行脚本", '')def js_callback(result):if result != '':QMessageBox.information(self, "JS脚本返回信息", str(result))self.statusBar().showMessage(f'成功执行JS脚本')self.webEngineView.page().runJavaScript(js_string, 0, js_callback)

(二)用户分别通过浏览器 GUI和PySide6 GUI进行操作

在该程序中,用户使用浏览器GUI进行题目选择、答题、提交答卷等点击交互操作,这里使用HTML+JavaScript+CSS实现交互界面的设计、渲染和浏览器内部逻辑处理。如以下JavaScript脚本,用以判断用户选择的答案是否正确。

JavaScript代码:

	function chooseAnswer() {let A = '';let B = '';let C = '';let D = '';let valueA = document.getElementById("radioA").checked;let valueB = document.getElementById("radioB").checked;let valueC = document.getElementById("radioC").checked;let valueD = document.getElementById("radioD").checked;if (valueA === true) {A = 'A';}if (valueB === true) {B = 'B';}if (valueC === true) {C = 'C';}if (valueD === true) {D = 'D';}let user_choose_answer = A + B + C + D;let daan = ti_ku.ti_mu[user_choose_number - 1].daan;let x = user_choose_answer.toLowerCase();let y = daan.toLowerCase();answers[user_choose_number - 1] = user_choose_answer;if (x === y) {alert('回答正确');fen_shu[user_choose_number - 1] = 1;if_answer[user_choose_number - 1] = 1;} else {alert('回答错误');fen_shu[user_choose_number - 1] = 0;if_answer[user_choose_number - 1] = 1;}}

该程序使用PySide6 GUI进行导入题库、保存答题记录、查看历史答题等交互操作,由于这些操作需要使用用户计算机本地资源,所以应使用python代码进行逻辑控制。如以代码,实现保存本次用户答题记录。

Python代码:

    def submit_answer_js(self):def js_callback(result):# js返回的本轮答题json结果,写入本地系统文件,并以系统用户名+时间.js形式保存在history文件夹中if result != '':js_result = str(result)save_dir = self.environment["answer_record_dir"] + os.path.sep + self.environment["cur_question_bank_id"]save_file_name = save_dir + os.path.sep + datetime.now().strftime('-%Y-%m-%d %H-%M-%S') + '.js'print(self.environment["cur_question_bank_id"])if not os.path.exists(save_dir):os.makedirs(save_dir)f = open(save_file_name, 'w', encoding='utf-8')f.write(js_result)f.close()self.statusBar().showMessage(f'已保存本次答题记录,如想查看历史答题记录可点"查看答题历史"按钮')if self.environment["cur_question_bank_id"] != '':self.webEngineView.page().runJavaScript("submit()", 0, js_callback)else:self.statusBar().showMessage(f'请先导入题库')

(三)使用PySide6 GUI获取用户计算机本地资源

由于安全问题,一般情况下浏览器是禁止直接获取用户计算机本地资源的,因此浏览器GUI无法通过JavaScript代码来获取存储在用户计算机中的题库。在该程序中,我们使用PySide6 GUI控件QFileDialog,通过编写Python代码来获取题库文件路径,接着使用os库读取题库数据。如以下python代码,实现获取题库文件路径,并读取excel题库文件数据传递到浏览器中。

Python代码:

    def import_question_bank(self):def js_callback(result):if result != '':self.statusBar().showMessage(f'成功导入选中题库')file_name, ok = QFileDialog.getOpenFileName(self, caption='Open file', dir=os.path.abspath('.'),filter="(*.xls)")if file_name != "":excel_data = excel2json.read_excel_to_json(file_name)# 根据内容生成唯一哈希码,并用该哈希码作为题库文件名,用于未来区分导入的是那一份题库save_file_name = hashlib.sha256(excel_data.encode()).hexdigest()self.environment["cur_question_bank_id"] = save_file_namejson_save_path = self.environment["question_bank_dir"] + os.path.sep + save_file_name + '.js'# 判断目录是否存在,不存在则新增if not os.path.exists(self.environment["question_bank_dir"]):os.makedirs(self.environment["question_bank_dir"])# 写入json格式内容,并保存为js文件encoded_data = base64.b64encode(excel_data.encode("gbk"))f = open(json_save_path, 'w', encoding='gbk')f.write(encoded_data.decode("gbk"))f.close()self.statusBar().showMessage(f'成功加载选中题库')self.webEngineView.page().runJavaScript("init('{}','{}');".format(self.environment["cur_question_bank_id"], encoded_data.decode("gbk")), 0,js_callback)else:self.statusBar().showMessage(f'导入题库失败,未选择文件或文件格式错误,当前仅支持xls格式')

五、遇到问题及解决方案

(一)如何把excel数据转换成json数据?

该程序的一个主要功能是导入本地题库,题库文件格式一般为:xls、xlsx、word、pdf等。但word和pdf文件涉及图像识别,实现起来比较复杂,所以博主这里只实现了xls和xlsx格式的导入功能。另外,由于后续需用浏览器GUI进行界面渲染,所以导入题库的数据最终应转成json格式,以便在浏览器环境中开展数据处理

excel格式数据转json格式数据博主之前也研究过,并写过一个python小脚本,所以这里直接拿来微调使用即可。具体实现可以参考下面这篇文章。Python|excel表格数据一键转json格式小工具|支持xlsx、xls格式转json|【源码+解析】

(二)如何向chrome内核传递带大量json数据参数的JavaScript代码?

上文提到,在PySide6中,可用webEngineView.page().runJavaScript()方法向浏览器传递待执行的JavaScript脚本。

查阅PySide6资料发现webEngineView的page()方法返回QWebEnginePage()对象,该对象拥有runJavaScript()方法,可以异步向浏览器发送js代码。

但该方法好像只支持传递字符串,不支持传递对象。因此,基于当前的对该方法的理解,只能把需向浏览器传递的脚本和数据都统一封装成一段完整代码字符串,再执行该方法。这过程还涉及统一字符串编码、保证JavaScript语法正确等问题,需要使用base64、encode等方法进行数据传递前后的编码处理,通过一系列编码转换,最终实现把题库中的大量excel数据传递至浏览器并处理,主要代码如下。

Python代码:

    def import_question_bank(self):def js_callback(result):if result != '':self.statusBar().showMessage(f'成功导入选中题库')file_name, ok = QFileDialog.getOpenFileName(self, caption='Open file', dir=os.path.abspath('.'),filter="(*.xls)")if file_name != "":excel_data = excel2json.read_excel_to_json(file_name)# 根据内容生成唯一哈希码,并用该哈希码作为题库文件名,用于未来区分导入的是那一份题库save_file_name = hashlib.sha256(excel_data.encode()).hexdigest()self.environment["cur_question_bank_id"] = save_file_namejson_save_path = self.environment["question_bank_dir"] + os.path.sep + save_file_name + '.js'# 判断目录是否存在,不存在则新增if not os.path.exists(self.environment["question_bank_dir"]):os.makedirs(self.environment["question_bank_dir"])# 写入json格式内容,并保存为js文件encoded_data = base64.b64encode(excel_data.encode("gbk"))f = open(json_save_path, 'w', encoding='gbk')f.write(encoded_data.decode("gbk"))f.close()self.statusBar().showMessage(f'成功加载选中题库')self.webEngineView.page().runJavaScript("init('{}','{}');".format(self.environment["cur_question_bank_id"], encoded_data.decode("gbk")), 0,js_callback)else:self.statusBar().showMessage(f'导入题库失败,未选择文件或文件格式错误,当前仅支持xls格式')

功能实现后对应的软件截图:
在这里插入图片描述

(三)如何区分不同的题库,同样的题库只保存一份?

hashlib.sha256是Python的一个内置模块,用于计算信息的SHA-256哈希值。这是一个计算机加密哈希函数的实例,它可以用于验证数据的完整性,或者生成数据的唯一哈希值。

该程序一开始只考虑到用户只导入一个题库进行复习,但如果用户导入第二份题库就会覆盖第一次导入的题库。为了解决该问题,使得程序支持多题库导入,首先要解决如何确保导入的题库具有唯一的标识,无论用户后续导入多少份、多少次题库,程序都可自动对题库进行去重,只保留不重复题库。博主这里使用python的hashlib库sha256()方法,使用题库内容生成唯一哈希码,并以此哈希码作为题库.js文件名,用以保证唯一性

Python代码:

        if file_name != "":excel_data = excel2json.read_excel_to_json(file_name)# 根据内容生成唯一哈希码,并用该哈希码作为题库文件名,用于未来区分导入的是那一份题库save_file_name = hashlib.sha256(excel_data.encode()).hexdigest()self.environment["cur_question_bank_id"] = save_file_namejson_save_path = self.environment["question_bank_dir"] + os.path.sep + save_file_name + '.js'# 判断目录是否存在,不存在则新增if not os.path.exists(self.environment["question_bank_dir"]):os.makedirs(self.environment["question_bank_dir"])# 写入json格式内容,并保存为js文件encoded_data = base64.b64encode(excel_data.encode("gbk"))f = open(json_save_path, 'w', encoding='gbk')f.write(encoded_data.decode("gbk"))f.close()self.statusBar().showMessage(f'成功加载选中题库')self.webEngineView.page().runJavaScript("init('{}','{}');".format(self.environment["cur_question_bank_id"], encoded_data.decode("gbk")), 0,js_callback)else:self.statusBar().showMessage(f'导入题库失败,未选择文件或文件格式错误,当前仅支持xls格式')

功能实现后对应的软件截图:
在这里插入图片描述

(四)如何保存来自浏览器GUI的答题数据,同样的答题记录只保存一份,并与对应的题库关联?

strftime()是“string format time”的缩写,主要用于格式化日期时间对象为自定义的字符串表示形式。

支持多题库导入,衍生除了另外一个新问题,当用户读取答题记录与当前所选题库不对应时,界面会出现显示错乱的BUG。因此,在每次保存答题记录、查看历史答题记录时应进行校验,保证答题记录和题库一一对应。这里有几个关键点:①用户的答题结果;②用户当前选择的题库;③当前的系统时间。需做以下几个操作:①把用户的答题结果转换成json格式字符串,用于保存为.js格式文件;②获取当前用户选择题库的哈希码,用于建立对应的答题记录一级目录,并以该哈希码命名目录;③获取当前系统时间,使用strftime()将系统时间转换成年月日时分秒格式,并以该格式命名答题记录.js文件的文件名。以下是参考代码:

JavaScript代码:

function submit() {let x = 0;let y = 0;for (let i = 0; i < ti_ku.number; i++) {x = x + fen_shu[i];y = y + if_answer[i];}alert('正确题数:' + x + '\n错误题数:' + (y - x) + '\n未作答:' + (ti_ku.number - y) );let de_fen = new Object();de_fen.answers=answers;de_fen.fen_shu=fen_shu;de_fen.if_answer=if_answer;return JSON.stringify(de_fen);de_fen = null}

Python代码:

    def submit_answer_js(self):def js_callback(result):# js返回的本轮答题json结果,写入本地系统文件,并以系统用户名+时间.js形式保存在history文件夹中if result != '':js_result = str(result)save_dir = self.environment["answer_record_dir"] + os.path.sep + self.environment["cur_question_bank_id"]save_file_name = save_dir + os.path.sep + datetime.now().strftime('-%Y-%m-%d %H-%M-%S') + '.js'print(self.environment["cur_question_bank_id"])if not os.path.exists(save_dir):os.makedirs(save_dir)f = open(save_file_name, 'w', encoding='utf-8')f.write(js_result)f.close()self.statusBar().showMessage(f'已保存本次答题记录,如想查看历史答题记录可点"查看答题历史"按钮')if self.environment["cur_question_bank_id"] != '':self.webEngineView.page().runJavaScript("submit()", 0, js_callback)else:self.statusBar().showMessage(f'请先导入题库')

功能实现后对应的软件截图:
在这里插入图片描述

六、完整源代码和可执行程序

到这里,对原来的纯HTML+JavaScript+CSS刷题程序的PySide6改造基本完成了,实现了文章开头所说的几个主要功能:
①导入题库功能,支持xlsx和xls格式;
②支持多题库导入及选择;
③支持保存答题记录;
④支持查看历史答题记录;
⑤界面由HTML+CSS实现,支持选题、标记正确、错误、未答题目、统计答题情况;
⑥逻辑由Python+JavaScript代码实现。

如果未来有时间还会继续研究和优化该程序。
以下是该Python程序的可执行文件下载地址:
疯狂刷题软件python版 - 使用PySide6自制刷题软件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/31711.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PostgreSQL中 FETCH FIRST ... WITH TIES 是查询结果中限制返回的行数

在 PostgreSQL 中&#xff0c;FETCH FIRST … WITH TIES 是一个在查询结果中限制返回的行数&#xff0c;但同时确保与最后一行具有相同排序值的所有行都被包括进来的子句。这通常与 ORDER BY 子句一起使用。 当您使用 FETCH FIRST n ROWS ONLY 时&#xff0c;您只会得到前 n 个…

四,SSM整合-前后端分离(实现分页+前后端校验)

分页与校验 实现功能07-分页显示列表需求分析/图解思路分析代码实现完成测试 实现功能08-带条件查询分页显示列表需求分析/图解思路分析代码实现 实现功能09-添加家居表单前端校验需求分析/图解思路分析代码实现 实现功能10-添加家居表单后端校验需求分析/图解思路分析代码实现…

华为海思CPU解读

安全可靠CPU测评结果&#xff08;华为海思篇&#xff09; 中国信息安全测评中心于2024年5月20日发布安全可靠测评结果公告&#xff08;2024年第1号&#xff09;&#xff0c;公布依据《安全可靠测评工作指南&#xff08;试行&#xff09;》的测评结果&#xff0c;自发布起有效期…

可视化数据科学平台在信贷领域应用系列七:自动机器学习(下篇)

在当今金融科技迅速发展的时代&#xff0c;自动机器学习&#xff08;AutoML&#xff09;逐步成为了信贷风控领域的重要工具。随着大数据和人工智能技术的进步以及信贷风险环境的快速变化&#xff0c;传统人工建模模式的时效性已经难以应对复杂多变的挑战。自动机器学习框架将数…

海外版coze前端代码助手

定位 解决前端同事的开发问题 参数配置 测试 支持 最屌的大模型及语音播报。 体验地址 海外版前端代码助手 需要魔法才能体验油

2024.6最最新版MySQL数据库安装(保姆级教程,不懂你捶我)

1.MySQL数据库下载 1.打开MySQL官网 如下页面 2.下翻网页到最底部,找到Download,点击第一个MySQL Community Server 3.选择自己需要的版本以及系统的MySQL: 4.跳转页面会有一个登录/注册页面,这里我们不鸟他,直接开始下载 2.MySQL数据库安装 1.双击我们刚刚下载的安装包 2.勾…

编码RNA Terc-53和透明质酸受体Hmmr可调节小鼠的衰老

近期&#xff0c;厦门大学王耿教授团队在Protein & Cell&#xff08;IF21.1&#xff09;上发表题为“Noncoding RNA Terc-53 and hyaluronan receptor Hmmr regulate ageing in mice.”的研究。研究团队构建了一系列Terc-53小鼠模型&#xff0c;发现Terc-53小鼠表现出与年龄…

艾尔登法环攻略教程 教你怎么达成怎么进入DLC的前置条件

《艾尔登法环》是一款黑暗幻想风开放世界角色扮演动作游戏&#xff0c;该游戏让玩家走进辽阔的场景与地下迷宫探索未知&#xff0c;挑战困难重重的险境&#xff0c;同时体验登场角色之间的利害关系谱成的群像剧。其广阔的开放世界、深邃的剧情探索、极具挑战性的战斗系统&#…

stable diffusion 模型融合

【抛砖引玉】GhostMixV2.0的制作过程及关于Checkpoint模型融合的一点经验 - 知乎大家好,我是Ghost_Shell,也是GhostMix的作者。本来想写一篇文章整体介绍一下模型,一些你们可能没察觉到,但我非常固执的理念,也算是模型的特性。结果发现写太长了,就分开两部分,第一部分是…

【C++ | 重载运算符】一文弄懂C++运算符重载,怎样声明、定义运算符,重载为友元函数

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; ⏰发布时间⏰&#xff1a;2024-06-21 2…

银河麒麟V10安装docker和docker-compose

1. 说明 系统镜像使用的是Kylin-Server-V10-SP3-2403-Release-20240426-x86_64.iso如果是在VMware中安装这个系统&#xff0c;需选择Ubuntu&#xff0c;如果选Centos会有问题。 尝试使用在线方式安装docker&#xff0c;报了很多错误&#xff0c;比较麻烦&#xff0c;建议使用离…

xss初识(xss-lab)

XSS跨站脚本 XSS漏洞概述 XSS被称为跨站脚本攻击&#xff08;Cross-site scripting&#xff09;&#xff0c;由于和CSS&#xff08;Cascading Style Sheets&#xff09; 重名&#xff0c;所以改为XSS。 XSS主要基于javascript语言完成恶意的攻击行为&#xff0c;因为javascri…

前端代码打包教程

一、 首先解压并进入源码包中&#xff0c;源码文件是下载的完整版安装包的 view/ 目录下,平台后台是 admin.zip ,商户后台是 mer.zip , H5/公众号/小程序是 uniapp.zip ,2.0级以上版本还有客服的源码包&#xff1b; 二、 打包&#xff0c;移动端和后台的打包方式不同 平台后台…

echarts+vue2实战(一)

目录 一、项目准备 二、(横向分页)柱状图 2.1、动态刷新 2.2、UI调整 2.3、分辨率适配 三、(竖向平移)柱状图 3.1、平移动画 3.2、不同数值显示不同颜色 四、(下拉切换)折线图 4.1、切换图表和分辨率适配 4.2、UI调整 五、(三级分类)饼图 5.1、数据切换 六、圆环…

使用Tkinter创建带查找功能的文本编辑器

使用Tkinter创建带查找功能的文本编辑器 介绍效果代码解析创建主窗口添加菜单栏实现文件操作实现查找 完整代码 介绍 在这篇博客中&#xff0c;我将分享如何使用Python的Tkinter库创建一个带有查找功能的简单文本编辑器。 效果 代码解析 创建主窗口 import tkinter as tkcl…

Offset Explorer 连接SASL PLAIN鉴权的Kafka

1、填写Kafka信息 2、配置鉴权信息 Security 选择 SASL PLAINTEXT JAAS Config 配置账号密码 org.apache.kafka.common.security.plain.PlainLoginModule required username"账号"password"密码";

[Vulnhub] Troll FTP匿名登录+定时任务权限提升

信息收集 IP AddressPorts Opening192.168.8.104TCP:21,22,80 $ nmap -sC -sV 192.168.8.104 -p- --min-rate 1000 Nmap scan report for 192.168.8.104 (192.168.8.104) Host is up (0.0042s latency). Not shown: 65532 closed tcp ports (conn-refused) PORT STATE SER…

openh264 宏块级码率控制源码分析

openh264 宏块级码率控制函数关系 宏块级核心函数分析 WelsRcMbInitGom函数 功能&#xff1a;openh264 码率控制框架中宏块级码率控制函数&#xff0c;根据是否启用GOM QP来决定如何设置宏块的QP值&#xff0c;以控制编码的质量和比特率。原理过程&#xff1a; 函数参数&…

“打造智能售货机系统,基于ruoyi微服务版本开源项目“

目录 # 开篇 售货机术语 1. 表设计说明 2. 页面展示 2.1 区域管理页面 2.2 合作商管理页面 2.3 点位管理页面 3. 建表资源 3.1 创建表的 SQL 语句&#xff08;包含字段备注&#xff09; 1. Region 表 2. Node 表 3. Partner 表 4. 创建 tb_vending_machine 表的 S…

【启明智显产品介绍】Model3C工业级HMI芯片详解专题(一)芯片性能

【启明智显产品介绍】工业级HMI芯片Model3C详解&#xff08;一&#xff09;芯片性能 Model3C 是一款基于 RISC-V 的高性能、国产自主、工业级高清显示与智能控制 MCU&#xff0c;配置平头哥E907&#xff0c;主频400MHz&#xff0c;强大的 2D 图形加速处理器、PNG/JPEG 解码引擎…