【问题标题】:Python Kivy Plots with MeshLinePlot confusionPython Kivy Plots 与 MeshLinePlot 混淆
【发布时间】:2018-09-06 09:23:46
【问题描述】:

我正在尝试为 Kivy 应用程序实现测量的实时绘图,但我不了解 kivy garden 库的内部工作原理。

我想要实现的目标:我想在 ScrollView 内有多个绘图,这样我就可以从字典中以编程方式添加多个实时绘图,如果它们占用更多,则滚动浏览它们空间超过一个屏幕高度。我遇到的主要问题是 Graph 的行为不像普通的小部件,而是像画布一样。我已经尝试使用 matplotlib 作为 backend_kivyagg 来实现这一点,但是我没有为每个 subplot that I created 设置固定大小。

有很多事情我不明白为什么它们会像它们那样发生。

from math import sin, cos

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.scrollview import ScrollView
from kivy.uix.widget import Widget

from kivy.garden.graph import Graph, MeshLinePlot


class Plot(Widget):
    def __init__(self):
        super(Plot, self).__init__()
        self.graph = Graph(xlabel="x", ylabel="y", x_ticks_minor=5, x_ticks_major=25, y_ticks_major=1,
                           y_grid_label=True, x_grid_label=True, x_grid=True, y_grid=True,
                           xmin=-0, xmax=100, ymin=-1, ymax=1, draw_border=False)
        # graph.size = (1200, 400)
        # self.graph.pos = self.center

        self.plot = MeshLinePlot(color=[1, 1, 1, 1])
        self.plot.points = [(x, sin(x / 10.)) for x in range(0, 101)]
        self.plot2 = MeshLinePlot(color=[1, 0, 0, 1])
        self.plot2.points = [(x, cos(x / 10.)) for x in range(0, 101)]
        self.add_widget(self.graph)

        self.graph.add_plot(self.plot)
        self.graph.add_plot(self.plot2)


class GraphLayoutApp(App):

    def build(self):
        scroll_view = ScrollView()
        grid_layout = GridLayout(cols=1, row_force_default=True, padding=20, spacing=20)
        graph = Plot()
        graph2 = Plot()
        label = Label(text="Hello World!")
        label2 = Label(text="Hello World!")
        grid_layout.add_widget(label)
        grid_layout.add_widget(graph)
        grid_layout.add_widget(label2)
        grid_layout.add_widget(graph2)
        scroll_view.add_widget(grid_layout)

        return scroll_view


if __name__ == '__main__':
    GraphLayoutApp().run()

问题

  1. 在 GraphLayoutApp 类中,我创建了两个对象 graph 和 graph2,但是如果我将它们添加到 GridLayout() 中,只会出现一个?如何 我可以添加多个图表吗?

  2. 还在类 GraphLayoutApp 的 build 方法中,我创建了两个标签。我想先显示第一个 label 然后是图表 然后是第二个标签label2。但在我看来,图表 始终显示在左下角。我想这必须做 与绘制它的画布,但我无法解决它。

【问题讨论】:

    标签: python plot kivy kivy-language


    【解决方案1】:

    这是一个修改后的版本:

    这里的问题是你让你的 Plot 继承自 Widget,它确实是框架中最基本的小部件,并且由于它不是布局,不管理你添加到它的子项中的任何内容,所以 @987654321 @ 你添加到它的小部件保留在默认大小/位置(分别为 [100, 100] 和 [0, 0]),因此它们彼此堆叠,我使用了 RelativeLayout,默认情况下将子级设置为自己的大小和位置,因此图形跟随小部件。另一种解决方案是简单地让 Plot 从 Graph 继承,因为它是唯一的孩子,并使用“self.add_plot”而不是“self.graph.add_plot”,并覆盖 Graph 参数,最好的解决方案可能是创建一个Plot 类的 KV 规则。但第一个解决方案是对您的代码进行最小的更改。

    您错过的一般原则是,在 kivy 中,小部件默认情况下不受任何位置/大小的限制,除非它们的父级是专门管理它的布局(就像 GridLayout 为您的标签所做的那样)。

    我还使 GridLayout 自动将自身调整为 minimum_size(由我在所有小部件中放置的硬编码大小确定),因此您实际上可以滚动。

    这段代码也是非常python驱动的,在kivy中,你通常想用KV做更多的事情,而不是用add_widget做静态的事情。

    from math import sin, cos
    
    from kivy.app import App
    from kivy.uix.gridlayout import GridLayout
    from kivy.uix.label import Label
    from kivy.uix.scrollview import ScrollView
    from kivy.uix.widget import Widget
    from kivy.uix.relativelayout import RelativeLayout
    
    from kivy.garden.graph import Graph, MeshLinePlot
    
    
    class Plot(RelativeLayout):
        def __init__(self, **kwargs):
            super(Plot, self).__init__(**kwargs)
            self.graph = Graph(xlabel="x", ylabel="y", x_ticks_minor=5, x_ticks_major=25, y_ticks_major=1,
                               y_grid_label=True, x_grid_label=True, x_grid=True, y_grid=True,
                               xmin=-0, xmax=100, ymin=-1, ymax=1, draw_border=False)
            # graph.size = (1200, 400)
            # self.graph.pos = self.center
    
            self.plot = MeshLinePlot(color=[1, 1, 1, 1])
            self.plot.points = [(x, sin(x / 10.)) for x in range(0, 101)]
            self.plot2 = MeshLinePlot(color=[1, 0, 0, 1])
            self.plot2.points = [(x, cos(x / 10.)) for x in range(0, 101)]
            self.add_widget(self.graph)
    
            self.graph.add_plot(self.plot)
            self.graph.add_plot(self.plot2)
    
    
    class GraphLayoutApp(App):
    
        def build(self):
            scroll_view = ScrollView()
            grid_layout = GridLayout(cols=1, padding=20, spacing=20, size_hint_y=None)
            grid_layout.bind(minimum_size=grid_layout.setter('size'))
            graph = Plot(size_hint_y=None, height=500)
            graph2 = Plot(size_hint_y=None, height=500)
            label = Label(text="Hello World!", size_hint_y=None)
            label2 = Label(text="Hello World!", size_hint_y=None)
            grid_layout.add_widget(label)
            grid_layout.add_widget(graph)
            grid_layout.add_widget(label2)
            grid_layout.add_widget(graph2)
            scroll_view.add_widget(grid_layout)
    
            # return grid_layout
            return scroll_view
    
    
    if __name__ == '__main__':
        GraphLayoutApp().run()
    

    【讨论】:

    • 加一并接受:)。感谢您的帮助!这解决了我的问题:)。现在我可以尝试实现实时的东西和以编程方式添加新图表。
    猜你喜欢
    • 1970-01-01
    • 2022-01-17
    • 2015-05-29
    • 2017-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多