一、整体思路
先介绍一下这一功能点的思路:
因为该软件是面对那些需要家长陪伴的孩子们的,所以,软件中增加“听写”环节,当然也可以面对自觉性比较高的孩子们。前一节完成了“待复习内容”展示,格式如下:
我希望: 1、增加一列(如最右侧的红框列),实现对该知识点复习结果的评判断。2、增加得分 满分100,根据当天复习的量,确定每个知识点的分值。如:当天复习10个知识点,则10分/个;当天复习20个,则5分/个。
二、增加“评卷”列
在数据库中,我设计了一列,叫“pass_or_no”,可以通过把此列筛选出来,达到增加一列的目的。在这一列中,可以增加两个按扭,一个是“正确”,一个是“错误”。形如:
2.1 在tableView 的列表中增加控件
思路:即在该列的每行都增加一个widget,该widget中有两个按扭,分别是“正确”和“错误”。实现这个widget的脚本如下:
def widget_ok(self):
widget_ok_ck = QWidget()
layout = QtWidgets.QHBoxLayout()
widget_ok_ck.setLayout(layout)
# 正确
btn_ok = QtWidgets.QPushButton('正确')
btn_ok.setStyleSheet('QPushButton{color:rgb(255, 0, 0)} ') # 正常是红色,按下去是灰色
# 错误
self.btn_error = QtWidgets.QPushButton('错误')
self.btn_error.setStyleSheet('QPushButton{color:rgb(255, 0, 0)} ') # 正常是红色,按下去是灰色
# btn_ok.setStyleSheet('QPushButton{color:rgb(255, 0, 0)}')
btn_ok.setFixedSize(100, 35)
layout.addWidget(btn_ok)
self.btn_error.setFixedSize(100, 35)
layout.addWidget(self.btn_error)
layout.setContentsMargins(0, 2, 0, 2)
layout.setAlignment(Qt.AlignCenter)
btn_ok.clicked.connect(self.btn_ok_func)
self.btn_error.clicked.connect(self.btn_error_func)
return widget_ok_ck
然后在tableview中逐行插入这一widget:
for i in range(self.qrModel.rowCount()):
self.ui.tableView.setIndexWidget(self.qrModel.index(i, 5), self.widget_ok())
三、增加得分功能
在评分之前,有几个需求需要先解决:
问题1:“评卷”widget中有两个按扭,而且每一行都有两个按钮,软件怎么知道哪个按钮被按下了? 这不同于前面常用的槽函数,每个button都有明确的名称,这里的“正确”按钮,都叫btn_ok,这里的“错误”按钮,都叫btn_error。
【答案】: 有一个sender函数能够获取到信号的发送者。
使用button = self.sender() ,即可。
问题2: 怎么确定所按按钮的位置
【答案】row = self.tableView.indexAt(button.parent().pos()).row()
其中 indexAt函数根据QPoint判断行。
完成以上问题后,就可以写两个按钮对应的函数了,以正确按钮为例:
def btn_ok_func(self):
button = self.sender() #发现有一个sender函数能够获取到信号的发送者
if button:
# 确定位置
row = self.ui.tableView.indexAt(button.parent().pos()).row() # indexAt函数根据QPoint判断行
self.rightTimes = self.rightTimes + 1
button.setEnabled(False)
button.setStyleSheet('QPushButton{color:rgb(99, 99, 99)}')
button.parent().children()[2].setEnabled(False)
button.parent().children()[2].setStyleSheet('QPushButton{color:rgb(99, 99, 99)}')
self.right_rate = 100 * self.rightTimes / (self.rightTimes + self.errorTimes)
self.lcd_refresh()
最终实现的效果如下:
四、将评卷结果回写数据库
因为每次复习,不只复习当天,还要复习以前的。如果复习的是今天的,则在“first_day”中写入评卷结果;如果复习的是前两天,则在“second_day”中写入评卷结果……如果复习的是前30天的,则在“thirtieth_day”中写入评卷结果。
思路比较清晰,也写了以下的脚本:
word_id = self.qrModel.record(row).value(0)
first_time = QDate.fromString(self.qrModel.record(row).value(4),'yyyy-MM-dd')
if first_time.addDays(1) == QDate.currentDate():
self.update_query.exec("update memory set first_day = 'pass' where word_id= " + word_id)
elif first_time.addDays(2) == QDate.currentDate():
self.update_query.exec("update memory set second_day = 'pass' where word_id= " + word_id)
elif first_time.addDays(6) == QDate.currentDate():
self.update_query.exec("update memory set sixth_day = 'pass' where word_id= " + word_id)
elif first_time.addDays(14) == QDate.currentDate():
self.update_query.exec("update memory set fourteenth_day = 'pass' where word_id=" + word_id)
elif first_time.addDays(30) == QDate.currentDate():
self.update_query.exec("update memory set thirtieth_day = 'pass' where word_id= " + word_id)
else:
pass
看上去很完美,增加断点后跟踪也没有问题,但是执行起来就闪退。
问题: 为什么一个看上去很正常,单步跟踪也很正常的SQL语句,在python+pyqt中运行时,会闪退?
【答案】:这个问题让花了我至少一个小时,不描述过程了,说说解决方案吧:
问题出在:exec("update memory set first_day = ‘pass’ where word_id= " + word_id) 的 word_id中。
想想一个字符串,怎么能加上一个int类呢? 用:str(word_id)代替,顺利解决问题。
好的,至此,一个具有基本复习功能的小应用就OK了。
希望对大家有帮助。
【The End!】