前面写了二个常用的控件,单选按钮、多选按钮、滚动区域控件,今天就用单选按钮结合按钮组、滚动区域来做一个单选题网上答题系统; 今天这个系统稍微有点复杂,不过也都是常用的语法,能全程把代码手撮下来,将会是一个很大的进步,希望业余朋友一定要坚持下来;毕竟学习是一件痛苦的事,不像刷短剧那么轻松。 送给还在坚持学习的每一个人:上坡路虽然是辛苦点,但坚持下来,回头再看看,你已经超过很多人了。以前,咱们创建的类都是继承自QWidget 这个空白窗口,但是今天为了避免窗口过长时,可以显示垂直和水平滚动条,我们可以直接继承自QScrollArea滚动区域控件;② 再创建一个QWidget窗口对象,把这个对象通过setWidget( )方法,设置给QScrollArea;③ 然后把所有创建的对象的父类都设置成QWidget就行了。
from PySide6.QtCore import Qtfrom PySide6.QtWidgets import QWidget, QApplication, QPushButton, QLabel, QRadioButton, QButtonGroup, QVBoxLayout, QHBoxLayout, QScrollArea
二、创建类System(QScrollArea) 继承自滚动区域class System(QScrollArea): def __init__(self): super().__init__() # 设置窗口标题 self.setWindowTitle("网上答题系统") # 设置滚动区域内部控件自动调整大小 self.setWidgetResizable(True) # 取消水平滚动条 self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # 设置样式表,可先跳过,后面有空了可以聊聊 self.setStyleSheet(""" QWidget {background-color: lightblue; font-size: 20px; } QPushButton {background-color: lightskyblue; } """) # 创建一个widget控件放置题目内容 self.widget = QWidget(self) # 在滚动区域内添加widget控件 self.setWidget(self.widget) # 创建垂直布局为主布局 self.main_layout = QVBoxLayout() # 设置网格布局为主布局 self.widget.setLayout(self.main_layout) self.main_layout.setAlignment(Qt.AlignTop) # 设置布局的水平和垂直间隔距离 self.main_layout.setSpacing(20) # 设置内容边距 self.main_layout.setContentsMargins(20, 20, 30, 10) # 题目信息如下 self.questions = [ { "title": "1、中华人民共和国成立时间是:", "options": ["A: 1950年10月1日", "B: 1950年5月1日", "C: 1949年10月1日", "D: 1949年1月1日"], "result": 3 # C选项 }, { "title": "2、中国历史上第一位皇帝是:", "options": ["A: 纣王", "B: 赢政", "C: 周武王", "D: 汉高祖"], "result": 2 # B选项 }, { "title": "3、四大洋中面积最大的是:", "options": ["A: 太平洋", "B: 大西洋", "C: 印度洋", "D: 北冰洋"], "result": 1 # A选项 }, { "title": "4、我车境内目前已经确认最早的古人类是:", "options": ["A: 北京人", "B: 元谋人", "C: 山顶洞人", "D: 蓝田人"], "result": 2 # B选项 }, { "title": "5、商朝的建立者是:", "options": ["A: 禹", "B: 汤", "C: 盘庚", "D: 纣"], "result": 2 # B选项 }, { "title": "6、目前世界上发现最重的青铜器是:", "options": ["A: 四羊方尊", "B: 司母戊鼎", "C: 毛公鼎", "D: 青铜立人像"], "result": 2 # B选项 }, ] # 创建按钮列表,为每个题目都要创建一个按钮组 self.button_groups = [] self.setup_01()
三、创建实例方法setup_01()并在其中创建控件def setup_01(self): label = QLabel("一、单项选择题,每题只有一个正确答案") self.main_layout.addWidget(label) # 用循环创建题目,并为每个题目选项创建水平布局 for i, question in enumerate(self.questions): # 创建__题目__ self.title = QLabel(question["title"]) self.main_layout.addWidget(self.title) # 为选项创建水平布局 hbox_layout = QHBoxLayout() group = QButtonGroup(self) # 用循环创建____题目选项 for option_id, option_text in enumerate(question["options"], start=1): # 循环创建四个单选按钮 同时 添加到水平布局中 radio_button = QRadioButton(option_text) hbox_layout.addWidget(radio_button) # 把单选按钮添加到按钮组中,并设置id 且 id从 1 开始 # id 1、2、3、4 对应 A、B、C、D 选项 group.addButton(radio_button, option_id) # 循环创建选项结束,把4个选项所在的___水平布局添加到主垂直布局中 self.main_layout.addLayout(hbox_layout) # 把创建的按钮组添加到列表中储存起来 self.button_groups.append(group) # 创建提交答案按钮 self.btn = QPushButton("提交答案", self) # 为按钮连接槽函数 (核对答案) self.btn.clicked.connect(self.check_answers) # 把按钮添加到主 垂直布局中 self.main_layout.addWidget(self.btn) # 结果(分数)展示 self.show_label_2 = QLabel() self.main_layout.addWidget(self.show_label_2)
四、创建提交答案按钮的槽函数,用来较核答案是否正确,并显示分数标签def check_answers(self): # 题目总个数 total_score = len(self.questions) # 变量分数score 原始值为 0 score = 0 # 结果展示内容列表 show_result = [] # 先判断,有没有选择答案 for i, group in enumerate(self.button_groups): # 先拿到按钮组中被选中的选项ID(1、2、3、4 分别与A、B、C、D 对应) selected_id = group.checkedId() # 拿到题目的正确答案 result result = self.questions[i]["result"] if selected_id == -1: show_result.append(f"第{i+1}题未作答") elif selected_id == result: score += 1 show_result.append(f"第{i+1}题正确") else: show_result.append(f"第{i+1}题错误") # 显示结果 show_text = f"得分:{score}/{total_score} \n" + "\n".join(show_result) self.show_label_2.setText(show_text) self.show_label_2.setAlignment(Qt.AlignCenter) self.show_label_2.setStyleSheet("color: red; font-weight: bold;")
if __name__ == "__main__": import sys app = QApplication(sys.argv) win = System() win.show() sys.exit(app.exec())
上面是一个网络答题系统的所有原码,本期的案例稍微有点复杂,如果能全程手撮一遍,将有很大的收获。