为了给小喇叭图像绑定点击事件,实现当用户点击按钮时,触发该事件对应的回调方法。
在方法内对于不同的系统Kivy使用不同的播放语音方法,
对于Windows系统 使用SoundLoader播放语音,
对于其他的Unix系统 使用Pyjnjus播放(Windows安装不太方便,打包时添加即可)。
打包不同的系统时 用不同的代码,而不是一蹴而就。
def play_word(self):
def play_word(self):
"""播放MP3文件"""
word = self.ids.word_to_study.text
storage_path = 'mp3/%s.mp3' % word
if os.name == 'nt':
self.window_play_word(storage_path)
elif os.name == 'posix':
self.unix_play_word(storage_path)
@staticmethod
def window_play_word(storage_path):
from kivy.core.audio import SoundLoader
sound = SoundLoader.load(storage_path)
sound.play()
@staticmethod
def unix_play_word(storage_path):
# 安装Pyjnius
from jnius import autoclass
MediaPlayer = autoclass('android.media.MediaPlayer')
player = MediaPlayer()
if player.isPlaying():
player.stop()
player.reset()
try:
player.setDataSource(storage_path)
player.prepare()
player.start()
except:
player.reset()
os.name
os.name
是 Python 的 os
模块中的一个属性,它返回一个字符串,指示正在使用的操作系统。这个属性对于编写跨平台代码时判断操作系统类型非常有用。
os.name
的返回值可能包括以下几种:
'posix'
: 表示 Unix-like 的操作系统,如 Linux, macOS(以前的 OS X), BSD, AIX 等。'nt'
: 表示 Windows 操作系统。'os2'
: 表示 OS/2 操作系统。'ce'
: 表示 Windows CE。'java'
: 表示 Java 虚拟机(JVM)。'riscos'
: 表示 RISC OS。
但需要注意的是,os.name
主要用于标识操作系统的类型,而不是具体的操作系统版本或发行版。
在编写跨平台代码时,你可以使用 os.name
来确定使用哪种方法或库来执行特定于操作系统的任务。但是,当可能的话,最好使用跨平台的库和工具,以减少对不同操作系统的特殊处理。
例如:
import os
if os.name == 'posix':
# Unix-like 系统代码
print("Running on a Unix-like system")
elif os.name == 'nt':
# Windows 系统代码
print("Running on Windows")
else:
# 其他系统代码
print("Running on an unknown system")
但是,对于音频播放这样的功能,通常可以使用跨平台的库(如 PyDub, soundfile, Kivy 的 SoundLoader 等),从而避免使用 os.name
来判断操作系统类型。
kivy.core.audio import SoundLoader
Audio — Kivy 2.3.0 documentation
from injus import autoclass
jnius
jnius
是一个 Python 库,它允许你在 Python 代码Kivy on Android — Kivy 2.3.0 documentation中与 Java 类进行交互,特别是在 Kivy 框架的 Android 应用中。jnius
提供了对 Java Native Interface (JNI) 的封装,使得 Python 开发者能够轻松地访问 Java 类库和 Android API。
在 Kivy 应用程序中,jnius
特别有用,因为 Kivy 支持跨平台开发,但某些特定于 Android 的功能可能需要使用 Java 代码来实现。通过使用 jnius
,你可以直接在 Python 代码中调用这些 Java 类和方法,而无需编写额外的 Java 代码或绑定库。
以下是使用 jnius
的一些基本步骤:
- 安装:如果你正在使用 Kivy 进行 Android 开发,
jnius
通常已经作为 Kivy 的一部分包含在内。但如果你需要单独安装它,可以通过 pip 进行安装。 - 导入:在你的 Python 代码中,你可以使用
from jnius import autoclass
来导入你想要的 Java 类。autoclass
会动态地加载指定的 Java 类。 - 使用:一旦你导入了 Java 类,你就可以像使用 Python 类一样使用它们。例如,你可以创建类的实例、调用方法、访问属性等。
下面是一个简单的示例,演示如何使用 jnius
来访问 Android 的 Toast
类并显示一条消息:
from jnius import autoclass
def show_toast(text):
Toast = autoclass('android.widget.Toast')
toast = Toast.makeText(android.getApplicationContext(), text, Toast.LENGTH_SHORT)
toast.show()
# 在某个地方调用这个函数
show_toast("Hello from Python!")
请注意,这个示例假设你正在一个 Android 环境中运行(比如一个 Kivy 应用),并且已经有了对 android
模块的引用(这个模块在 Kivy 的 Android 环境中是可用的)。
总之,jnius
是一个强大的工具,它允许 Python 开发者在 Android 应用中轻松地使用 Java 类和库。
Kivy on Android — Kivy 2.3.0 documentation
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:
# 先清除所有widgets
pass
else:
# 清除存在的三个按钮和标签
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)
self.ids.word_to_study.text = rows[0][1]
self.ids.phonetic.text = rows[0][3]
.clear_widgets()
.clear_widgets()
并不是所有GUI库都内置的一个通用方法。然而,这个方法在Kivy的BoxLayout
、GridLayout
、StackLayout
等布局类中是一个常见的方法,用于清除布局中的所有子部件(widgets)。
例如,在Kivy中,如果你有一个BoxLayout
,并且你想清除其中的所有子部件。
点击屏幕任意一点实现点击效果:
def anywhere_touch_down():
def anywhere_touch_down(self, instance, args):
"""单击任意位置都会执行这个方法"""
print("info.py anywhere_touch_down is running")
self.ids.main_box.unbind(on_touch_down=self.anywhere_touch_down)
self.play_word()
self.show_detail_word()
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:
# 先清除所有widgets
pass
else:
# 清除存在的三个按钮和标签
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)
self.ids.word_to_study.text = rows[0][1]
self.ids.phonetic.text = rows[0][3]
个人总结分析: 两函数之间关系互动维妙维俏,运维顺畅,若流水入明渠,融会贯通。
部分布局及其组件隐藏
展示 def show_detail_word(self):
def show_detail_word(self):
"""显示被隐藏的部分"""
word = self.ids.word_to_study.text
sql = "SELECT * FROM word WHERE word = '%s'" % word
rows = select_data(sql)
self.ids.main_box.clear_widgets(children=[self.ids.box_button_anchor, self.ids.three_labels_box])
self.ids.main_box.add_widget(self.ids.three_labels_box)
self.ids.main_box.add_widget(self.ids.box_button_anchor)
from MRWord.utils.common import sub_str_len
self.ids.word_to_study.text = rows[0][1]
self.ids.explain_word.text = sub_str_len(rows[0][2].strip(), 3)
self.ids.phonetic.text = rows[0][3]
self.ids.examples_en.text = rows[0][4]
self.ids.examples_cn.text = rows[0][5]