MRWord\pages\infopage\info.py
def read_random_word(self)
def read_random_word(self):"""随机读取一条数据"""sql = "SELECT * FROM word WHERE id = (SELECT word_id FROM today ORDER BY RANDOM() limit 1)"rows = select_data(sql)if len(rows) == 0:# 先清除所有widgetspasselse:# 清除存在的三个按钮和标签self.ids.main_box.clear_widgets(children=[self.ids.three_labels_box, self.ids.box_button_anchor])# 绑定点击任意位置执行方法self.ids.main_box.bind(on_touch_down=self.anywhere_touch_down)print(rows)self.ids.word_to_study.text = rows[0][1]self.ids.phonetic.text = rows[0][3]
sql = "SELECT * FROM word WHERE id = (SELECT word_id FROM today ORDER BY RANDOM() limit 1)"
这个SQL查询语句的目的是从一个名为word
的表中随机选择一个与today
表相关的单词。具体解释如下:
-
外部查询:
SELECT * FROM word WHERE id = ...
这部分查询是从word
表中选择所有列(*
表示所有列),但只选择那些其id
满足某个条件的行。
2. 内部查询(子查询):
(SELECT word_id FROM today ORDER BY RANDOM() LIMIT 1)
这是一个子查询,它做了以下几件事:
* 从`today`表中选择`word_id`列。
* 使用`ORDER BY RANDOM()`对这些`word_id`进行随机排序。
* 使用`LIMIT 1`只选择排序后的第一个`word_id`。
因此,整个查询的逻辑是:首先,从today
表中随机选择一个word_id
。然后,使用这个随机选择的word_id
从word
表中选择相应的行。
但是,需要注意的是,如果today
表中没有word_id
与word
表中的id
匹配,那么这个查询将不会返回任何结果。另外,如果today
表为空,那么子查询可能会返回一个错误(取决于数据库的具体实现),因为不能从空集中选择一个随机元素。
为了避免这种情况,你可能需要添加一些额外的逻辑来处理这些情况,例如使用COALESCE
或IFNULL
(取决于你的数据库系统)来提供一个默认值,或者确保today
表在查询之前至少有一个条目。
MRWord\db\sqlite3_connect.py
def select_data(sql):
def select_data(sql):"""查询数据"""# cursor.execute('select * from word where id=?', ('1',))conn = sqlite3.connect(db_path)try:cursor = conn.cursor()# 执行sqlcursor.execute(sql)response = cursor.fetchall()cursor.close()return responseexcept Exception as e:logging.warning('Exception:%s' % e)finally:conn.close()
SQLiteStudio 中的word 数据库
添加print (rows)后得到的值
[(4, 'mail', 'n. 邮件;邮政,邮递;盔甲\nvt. 邮寄;给…穿盔甲\nvi. 邮寄;寄出\nn. (Mail)人名;(法)马伊\n\n\n', '[meɪl]', ' Your cheque is in the mail. ', '你的支票在邮寄中。', None, 4, '2019-11-19 16:47:46', 0)]
在给出的rows
列表中,rows[0]
是一个包含多个元素的元组。根据Python的索引规则,rows[0][1]
表示访问这个元组的第二个元素(因为索引是从0开始的),而rows[0][3]
表示访问这个元组的第四个元素。
因此:
rows[0][1]
是'mail'
,这是元组的第二个元素。rows[0][3]
是'[meɪl]'
,这是元组的第四个元素。
所以:
rows[0][1]
的值是'mail'
rows[0][3]
的值是'[meɪl]'
既然 数据 正常,为什么显示是一坨黑色或白色的方块儿呢?
原来是在kv文件中,其父容器名字写错了,应该写Label
ImageButton
是一个自定义的类,它结合了ButtonBehavior
和Image
类的特性。但是,您尝试在 Kivy 语言(.kv
文件)中直接定义AnchorLayout
和ImageButton
的布局,这是不正确的,因为.kv
文件通常用于定义界面布局,而不是类定义。
ImageButton
自定义类可能需要您自己实现显示文本的逻辑,因为Image
控件默认不支持文本显示。如果您想要文本和图片同时显示,您可能需要使用其他方法,比如将Label
和Image
放在一个布局中,或者使用背景图片和文本属性来模拟一个图像按钮。假设您已经有了
ImageButton
类,并且这个类能够显示文本(这通常不是Image
控件的标准功能,所以您可能需要自定义绘制逻辑),那么font_name
属性应该被设置在ImageButton
类的构造函数中或者通过其他方式在 Python 代码中设置,而不是在.kv
文件中。
ids.phonetic.text = '[meɪl]'
这行代码看起来像是在 Python 代码中设置的,但它不会直接作用在.kv
文件中定义的界面元素上。您需要在.kv
文件中为ImageButton
设置一个属性(比如text
,如果您已经实现了这个属性),或者在 Python 代码中通过引用该按钮的实例来设置它。关于黑色方块的问题,这可能是由于
ImageButton
实际上是一个图像控件,并且您没有为它指定任何图像源(source
属性),所以它只显示了一个默认的或空白的图像区域。如果您想要显示文本,您需要使用Label
或者其他支持文本的控件,并可能将其背景设置为透明或图像。为了修复这个问题,您应该:
- 在 Python 代码中定义
ImageButton
类(如果还没有的话),并实现显示文本的逻辑(如果需要的话)。- 在
.kv
文件中定义您的界面布局,使用ImageButton
(如果它支持文本)或者其他控件(如Button
和Image
的组合)来创建您想要的图像按钮效果。- 确保
font_name
和其他相关属性在 Python 代码中或通过.kv
文件被正确设置。- 如果
ImageButton
是一个图像控件,并且您想要显示文本,考虑使用Label
控件,并可能将其与图像控件结合使用。
如图就显示正常啦。