You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Kivy中用kivy.graphics.line绘制的宽图表添加ScrollView?

实现Kivy图表横向滚动查看

我用kivy.graphics.line绘制了一个图表,当图表宽度超过窗口时,只能通过拉大窗口才能查看完整内容。想给图表添加ScrollView,实现宽度超出时可滚动查看完整图表。

修改后的实现代码

main.py

from kivymd.app import MDApp
from kivy.uix.screenmanager import Screen
from kivy.lang import Builder
from kivy.graphics import Color, Line
from kivy.properties import ObjectProperty

class Graph(Screen):
    graph_container = ObjectProperty(None)  # 绑定绘图容器

    def drawLine(self):
        # 清空之前的绘图内容
        self.graph_container.canvas.before.clear()
        
        z = 18
        Xs = 50
        Ys = 150
        Step = 50
        h0=3
        h1 = 40
        h2 = 80
        h3 = 90
        s = 1.5
        
        # 计算图表实际宽度,设置容器宽度(加20留边距)
        max_x = Xs + Step//2 + (z + s)*Step
        self.graph_container.width = max_x + 20
        
        with self.graph_container.canvas.before:
            Color(0.2, 0.2, 0.2, 1)
            for i in range(1,z+2):
                Line(points=[Xs+(i*Step), Ys, Xs+(i*Step), Ys+h1],width=1.4)
            Line(points=[Xs+Step, Ys, Xs+((z+1)*Step), Ys],width=1.4)
            Line(points=[Xs+Step, Ys+h1, Xs+((z+1)*Step), Ys+h1],width=1.4)

            Color(1, 0.2, 0.2, 1)
            for i in [1,7,13]:
                Line(points=[Xs+Step//2+(i*Step), Ys+h1+h2, Xs+Step//2+((i+s)*Step), Ys+h1+h2+h3],width=2)
                Line(points=[Xs+Step//2+(i*Step), Ys+h0+h1, Xs+Step//2+(i*Step), Ys+h1+h2],width=2)
            for i in [4,10,16]:
                Line(points=[Xs+Step//2+(i*Step), Ys+h1+h2, Xs+Step//2+((i-s)*Step), Ys+h1+h2+h3],width=2)
                Line(points=[Xs+Step//2+(i*Step), Ys+h0+h1, Xs+Step//2+(i*Step), Ys+h1+h2],width=2)

            Color(0.2, 1, 0.2, 1)
            for i in [3,9,15]:
                Line(points=[Xs+Step//2+(i*Step), Ys+h1+h2, Xs+Step//2+((i+s)*Step), Ys+h1+h2+h3],width=2)
                Line(points=[Xs+Step//2+(i*Step), Ys+h0+h1, Xs+Step//2+(i*Step), Ys+h1+h2],width=2)
            for i in [6,12,18]:
                Line(points=[Xs+Step//2+(i*Step), Ys+h1+h2, Xs+Step//2+((i-s)*Step), Ys+h1+h2+h3],width=2)
                Line(points=[Xs+Step//2+(i*Step), Ys+h0+h1, Xs+Step//2+(i*Step), Ys+h1+h2],width=2)
            
            Color(0.2, 0.2, 1, 1)
            for i in [17,5,11]:
                Line(points=[Xs+Step//2+(i*Step), Ys+h1+h2, Xs+Step//2+((i+s)*Step), Ys+h1+h2+h3],width=2)
                Line(points=[Xs+Step//2+(i*Step), Ys+h0+h1, Xs+Step//2+(i*Step), Ys+h1+h2],width=2)
            for i in [2,8,14]:
                Line(points=[Xs+Step//2+(i*Step), Ys+h1+h2, Xs+Step//2+((i-s)*Step), Ys+h1+h2+h3],width=2)
                Line(points=[Xs+Step//2+(i*Step), Ys+h0+h1, Xs+Step//2+(i*Step), Ys+h1+h2],width=2)

Builder.load_file("Graph.kv")
class myapp(MDApp):
    def build(self):
        return Graph()

myapp().run()

Graph.kv

<Graph>:
    graph_container: graph_container
    MDGridLayout:
        cols:1
        size: root.size
        pos: root.pos
        
        MDFillRoundFlatButton:
            text:"绘图"
            on_release: root.drawLine()
        
        ScrollView:
            do_scroll_x: True  # 开启横向滚动
            do_scroll_y: False  # 关闭纵向滚动
            size_hint_y: 0.9  # 分配90%高度给滚动区域
            
            FloatLayout:
                id: graph_container
                size_hint_x: None  # 禁用宽度自适应,使用计算出的图表宽度
                height: self.parent.height  # 高度匹配滚动区域

关键修改说明

  1. 新增绘图容器:用FloatLayout作为图表的载体,所有绘图操作都在这个容器的canvas上进行,避免直接绘制在Screen上(Screen尺寸与窗口绑定,无法滚动)。
  2. 设置容器宽度:计算图表的最大横向坐标,设置容器宽度为该值加边距,让ScrollView识别出内容超出视口,触发滚动。
  3. 配置ScrollView:开启横向滚动、关闭纵向滚动,设置合理的尺寸比例,确保按钮和滚动区域布局协调。
  4. 清空旧绘图:每次点击绘图按钮时先清空容器canvas,避免重复绘制导致内容叠加。

内容的提问来源于stack exchange,提问作者yosef podine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 10:32:34