【问题标题】:Autoresizing Canvas in a Kivy App在 Kivy 应用程序中自动调整画布大小
【发布时间】:2017-06-04 14:32:51
【问题描述】:

我只在 python 中编写我的第一个 Kivy 应用程序(我暂时避免使用 kv)。我创建了一个名为 WorldviewWidget 的自定义小部件,我正试图将它用作绘图的地方。使用按钮小部件,我只需提供 size_hint 和 pos_hint,它们就会显示在我想要它们的位置。但是对于我的小部件,我不知道如何使用 size_hint 和 position_hint 来调整我在 WorldviewWidget 中绘制的矩形的大小。这是代码。提前致谢!

#! /usr/bin/python
from kivy.app import App
from kivy.graphics import *
from kivy.core.window import Window
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.widget import Widget
from kivy.uix.button import Button


class WorldviewWidget(Widget):
    def __init__(self, **kwargs):
        super(WorldviewWidget, self).__init__(**kwargs)

        self.canvas.clear()
        print self.size, self.pos

        with self.canvas:
            Color(1, 0, 0, 1, mode='rgba')
            # HELP! I want the rectangle to be resized when the window changes size so that it always takes up the same proportion of the screen.
            self.rect = Rectangle(size=???, pos=???)    


class JFROCS_App(App):

    def build(self):
        Window.clearcolor = [1,1,1,1]
        parent = FloatLayout(size=Window.size)

        worldview = WorldviewWidget(size_hint=(0.4, 0.4), pos_hint = {'x':0.2, 'y':0.2})
        parent.add_widget(worldview)


        start_btn = Button(text='Start', size_hint=(0.1, 0.1), pos_hint={'x':.02, 'y':.7}, background_color=[0,1,0,1])
        start_btn.bind(on_release=self.start_simulation)
        parent.add_widget(start_btn)

        pause_btn = Button(text='Pause', size_hint=(0.1,0.1), pos_hint={'x':.02, 'y':.6}, background_color=[1,1,0,1])
        pause_btn.bind(on_release=self.pause_simulation)
        parent.add_widget(pause_btn)

        stop_btn = Button(text='Stop', size_hint=(0.1,0.1), pos_hint={'x':.02, 'y':.5}, background_color=[1,0,0,1])
        stop_btn.bind(on_release=self.stop_simulation)
        parent.add_widget(stop_btn)

        return parent

    def start_simulation(self, obj):
        print "You pushed the start button!"
    def pause_simulation(self, obj):
        print "You pushed the pause button!"
    def stop_simulation(self, obj):
        print "You pushed the stop button!"

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

【问题讨论】:

    标签: python widget kivy autoresize


    【解决方案1】:

    我认为这种任务注定要使用 kivy 语言,但这里有一个 Python 解决方案。基本上,我使用了bind-方法让您的小部件监听其父级size 的变化。请查看this,了解有关此机制的更多信息。

    from kivy.app import App
    from kivy.graphics import *
    from kivy.core.window import Window
    from kivy.uix.floatlayout import FloatLayout
    from kivy.uix.widget import Widget
    from kivy.uix.button import Button
    
    
    class WorldviewWidget(Widget):
        def __init__(self, **kwargs):
            super(WorldviewWidget, self).__init__(**kwargs)
    
            self.canvas.clear()
            print self.size, self.pos
    
            with self.canvas:
                Color(1, 0, 0, 1, mode='rgba')
                # *changed* ##############################################
                self.rect = Rectangle(size=self.size, pos=self.pos)    
    
        # *new* ##########################################################
        def update_size(self, instance, new_size):
            print "UPDATING SIZE", instance, new_size
            self.size[0] = new_size[0] * 0.4
            self.size[1] = new_size[1] * 0.4
            self.rect.size = self.size
            self.pos[0] = self.parent.size[0] * 0.2
            self.pos[1] = self.parent.size[1] * 0.2
            self.rect.pos = self.pos
    
    class JFROCS_App(App):
    
        def build(self):
            Window.clearcolor = [1,1,1,1]
            parent = FloatLayout(size=Window.size)
    
            # *changed* ##################################################
            worldview = WorldviewWidget(size=(0.4*parent.size[0], 0.4*parent.size[1]),
                                        pos=(0.2*parent.size[0], 0.2*parent.size[1]))
            # makes sure that the widget gets updated when parent's size changes:
            parent.bind(size=worldview.update_size)
            parent.add_widget(worldview)
    
    
            start_btn = Button(text='Start', size_hint=(0.1, 0.1), pos_hint={'x':.02, 'y':.7}, background_color=[0,1,0,1])
            start_btn.bind(on_release=self.start_simulation)
            parent.add_widget(start_btn)
    
            pause_btn = Button(text='Pause', size_hint=(0.1,0.1), pos_hint={'x':.02, 'y':.6}, background_color=[1,1,0,1])
            pause_btn.bind(on_release=self.pause_simulation)
            parent.add_widget(pause_btn)
    
            stop_btn = Button(text='Stop', size_hint=(0.1,0.1), pos_hint={'x':.02, 'y':.5}, background_color=[1,0,0,1])
            stop_btn.bind(on_release=self.stop_simulation)
            parent.add_widget(stop_btn)
    
            return parent
    
        def start_simulation(self, obj):
            print "You pushed the start button!"
        def pause_simulation(self, obj):
            print "You pushed the pause button!"
        def stop_simulation(self, obj):
            print "You pushed the stop button!"
    
    if __name__ == '__main__':
        JFROCS_App().run()
    

    看看 kivy 语言——它会为你处理所有的绑定:)

    【讨论】:

    • 谢谢!我一定会研究语言。我只是想先了解它在幕后做了什么:)
    猜你喜欢
    • 2014-07-29
    • 2014-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    • 2018-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多