如何修改Kivy中ScrollView背景色并在其上显示文本?
修改Kivy ScrollView背景色的方法
ScrollView本身没有直接的background_color属性,你可以通过两种实用方式修改它的背景:
方法一:通过Canvas绘制背景
直接在ScrollView的canvas.before层添加颜色矩形,覆盖整个控件区域,确保背景跟随ScrollView的大小和位置变化:
在你的btn_press方法中,创建ScrollView后添加以下代码:
sc = ScrollView() # 设置背景色 with sc.canvas.before: Color(0.2, 0.3, 0.4, 1) # RGBA格式,这里是深蓝色 self.bg_rect = Rectangle(size=sc.size, pos=sc.pos) # 绑定尺寸和位置,保证背景随ScrollView变化 sc.bind(size=lambda _, size: setattr(self.bg_rect, 'size', size)) sc.bind(pos=lambda _, pos: setattr(self.bg_rect, 'pos', pos))
方法二:嵌套布局作为背景
在ScrollView内部先添加一个BoxLayout,给这个布局设置背景色,再把文本Label放入其中。同时要给Label设置size_hint_y=None,让它的高度自适应文本内容:
修改btn_press中的代码片段:
sc = ScrollView() # 创建带背景的容器布局 bg_layout = BoxLayout(orientation='vertical', size_hint_y=None) bg_layout.bind(minimum_height=bg_layout.setter('height')) # 自适应高度 bg_layout.background_color = (0.9, 0.9, 0.9, 1) # 浅灰色背景 bg_layout.background_normal = '' # 移除默认背景图 # 创建书籍文本Label book_label = Label(text=f'{data}', color=(0,0,0,1), size_hint_y=None, markup=False) book_label.bind(texture_size=lambda _, size: setattr(book_label, 'height', size[1])) bg_layout.add_widget(book_label) sc.add_widget(bg_layout)
完整修改后的代码
以下是采用方法二的完整代码,同时优化了文本段落格式:
from kivy.app import App from kivy.uix.button import Button from kivy.uix.label import Label from kivy.uix.boxlayout import BoxLayout from bs4 import BeautifulSoup from kivy.uix.scrollview import ScrollView import requests class MyButton(Button): color = (0, 0, 0, 1) valign = 'bottom' padding_y = 10 background_color = (.93, .91, .67, 1) background_normal = '' class Box(BoxLayout): orientation = "vertical" padding = [5,5,5,5] spacing = 10 def on_kv_post(self, widget): self.add_widget(MyButton(text='И. С. Тургенев. «Отцы и дети»', on_press=self.btn_press)) def btn_press(self, instance): self.clear_widgets() sc = ScrollView() # 创建背景布局 bg_layout = BoxLayout(orientation='vertical', size_hint_y=None) bg_layout.bind(minimum_height=bg_layout.setter('height')) bg_layout.background_color = (0.95, 0.92, 0.85, 1) # 米白色背景 bg_layout.background_normal = '' # 爬取书籍内容 x = 1 data = '' while True: if x == 1: url = "http://loveread.ec/read_book.php?id=12021&p=1" elif x < 4: url = f"http://loveread.ec/read_book.php?id=12021&p={x}" else: break request = requests.get(url) soup = BeautifulSoup(request.text, "html.parser") teme = soup.find_all("p", class_="MsoNormal") for temes in teme: data += temes.text + '\n\n' # 添加换行分隔段落 x += 1 # 创建自适应高度的文本标签 book_label = Label(text=data, color=(0,0,0,1), size_hint_y=None, markup=False) book_label.bind(texture_size=lambda _, size: setattr(book_label, 'height', size[1])) bg_layout.add_widget(book_label) sc.add_widget(bg_layout) self.add_widget(sc) class MyApp(App): def build(self): return Box() if __name__ == "__main__": MyApp().run()
关键说明
- 方法一适合简单场景,无需额外布局,直接通过Canvas绘制背景。
- 方法二更灵活,方便后续添加其他控件;Label必须设置
size_hint_y=None并绑定texture_size,否则文本会被截断。 - 颜色值为RGBA格式,数值范围0-1,可根据需求自由调整。
内容的提问来源于stack exchange,提问作者NewbieTM
相关产品推荐
相关产品推荐

