kivy开始使用kivy


备注

Kivy是一个开源Python库,用于快速开发跨平台用户界面。可以使用相同的代码库为Linux,Windows,OS X,Android和iOS开发Kivy应用程序。

图形通过OpenGL ES 2呈现,而不是通过本机小部件呈现,从而在操作系统之间产生相当统一的外观。

在Kivy中开发接口可选地涉及使用kvlang,一种支持类似python的表达式和python互操作的小语言。与仅使用Python相比,使用kvlang可以极大地简化用户界面的开发。

Kivy可以免费使用(目前在麻省理工学院的许可下),并获得专业支持。

安装和设置

视窗

如何安装Kivy有两种选择:

首先确保python工具是最新的。

python -m pip install --upgrade pip wheel setuptools
 

然后安装基本依赖项。

python -m pip install docutils pygments pypiwin32 kivy.deps.sdl2 kivy.deps.glew
 

虽然Kivy已经拥有音频和视频供应商,但GStreamer需要更高级的东西。

python -m pip install kivy.deps.gstreamer --extra-index-url https://kivy.org/downloads/packages/simple/
 

为简化起见,以下文本中的<python> 表示带有python.exe 文件的目录的路径。

  1. wheel包提供了编译的Kivy,但删除了cython 源组件,这意味着核心代码无法使用这种方式重新编译。但是,Python代码是可编辑的。

    稳定版的Kivy可在pypi上找到。

    python -m pip install kivy
     

    官方存储库中的最新版本可通过谷歌驱动器上的夜间制造轮子获得。访问与您的python版本匹配的文档中的链接。下载适当的轮后,重命名它以匹配此示例的格式并运行命令。

    python -m pip install C:\Kivy-1.9.1.dev-cp27-none-win_amd64.whl
     
  2. 资源

    从源代码安装Kivy比使用轮子需要更多必需的依赖项,但安装更灵活。

    使用这些行在<python>\Lib\distutils\distutils.cfg 创建一个新文件,以确保将正确的编译器用于源代码。

    [build]
    compiler = mingw32
     

    然后需要编译器。使用已安装的一些,或下载mingwpy 。诸如gcc.exe 类的重要文件将位于<python>\Scripts

    python -m pip install -i https://pypi.anaconda.org/carlkl/simple mingwpy
     

    不要忘记设置环境变量让Kivy知道应该使用哪些提供者。

    set USE_SDL2=1
    set USE_GSTREAMER=1
     

    现在安装编译所需的其他依赖项。

    python -m pip install cython kivy.deps.glew_dev kivy.deps.sdl2_dev
    python -m pip install kivy.deps.gstreamer_dev --extra-index-url https://kivy.org/downloads/packages/simple/
     

    检查Paths 部分以确保正确设置所有内容并安装Kivy。选择以下选项之一:

    python -m pip install C:\master.zip
    python -m pip install https://github.com/kivy/kivy/archive/master.zip
     

路径

Kivy需要从某些依赖项访问二进制文件。这意味着正确的文件夹必须位于环境的PATH 变量上。

set PATH=<python>\Tools;<python>\Scripts;<python>\share\sdl2\bin;%PATH%
 

这样,Python IDLE IDE就可以包含在<python>\Lib\idlelib; 。然后将idle 写入控制台,IDLE将准备好使用Kivy。

简化它

为避免重复设置环境变量,请以这种方式设置每个必需的路径,或者将这些行放入<python> 的批处理( .bat )文件:

set PATH=%~dp0;%~dp0Tools;%~dp0Scripts;%~dp0share\sdl2\bin;%~dp0Lib\idlelib;%PATH%
cmd.exe
 

要在安装后运行Kivy项目,请运行cmd.exe 或批处理文件并使用python <filename>.py

在Ubuntu上安装

对于使用kivy示例打开终端并运行以下命令在ubuntu上安装kivy

首先添加ppa

 sudo add-apt-repository ppa:kivy-team/kivy
 

安装kivy

 sudo apt-get install python-kivy
 

对于安装kivy示例

 sudo apt-get install python-kivy-example
 

运行简单应用程序和与小部件交互的不同方法

大多数kivy应用程序都以这种结构开头:

from kivy.app import App

class TutorialApp(App):
    def build(self):
        return 
TutorialApp().run()
 

有几种方法可以从这里开始:

下面的所有代码(示例1和3除外)都具有相同的小部件和类似功能,但显示了构建应用程序的不同方式。

示例1:返回单个小部件(简单的Hello World应用程序)

from kivy.app import App
from kivy.uix.button import Button
class TutorialApp(App):
    def build(self):
        return Button(text="Hello World!")
TutorialApp().run()
 

示例2:返回多个小部件+按钮打印标签的文本

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.button import Button

class TutorialApp(App):
    def build(self):
        mylayout = BoxLayout(orientation="vertical")
        mylabel = Label(text= "My App")
        mybutton =Button(text="Click me!")  
        mylayout.add_widget(mylabel)
        mybutton.bind(on_press= lambda a:print(mylabel.text))
        mylayout.add_widget(mybutton)
        return mylayout
TutorialApp().run()
 

示例3:使用类(单个小部件)+按钮打印“我的按钮”

from kivy.app import App
from kivy.uix.button import Button

class Mybutton(Button):
    text="Click me!"
    on_press =lambda a : print("My Button")    
    
class TutorialApp(App):
    def build(self):
        return Mybutton()
TutorialApp().run()
 

例4:它与ex相同。 2但它显示了如何使用一个类

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.button import Button

class MyLayout(BoxLayout):
    #You don't need to understand these 2 lines to make it work!
    def __init__(self, **kwargs):
        super(MyLayout, self).__init__(**kwargs)
        
        self.orientation="vertical"
        mylabel = Label(text= "My App")
        self.add_widget(mylabel)
        mybutton =Button(text="Click me!")
        mybutton.bind(on_press= lambda a:print(mylabel.text))
        self.add_widget(mybutton)
        
class TutorialApp(App):
    def build(self):
        return MyLayout()
TutorialApp().run()
 

用.kv语言

例5:相同但显示如何 python中使用kv语言

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout 
# BoxLayout: it's in the python part, so you need to import it

from kivy.lang import Builder
Builder.load_string("""
<MyLayout>
    orientation:"vertical"
    Label: # it's in the kv part, so no need to import it
        id:mylabel
        text:"My App"
    Button:
        text: "Click me!"
        on_press: print(mylabel.text)
""")
class MyLayout(BoxLayout):
    pass
class TutorialApp(App):
    def build(self):
        return MyLayout()
TutorialApp().run()
 

**示例6:与Tutorial.kv 文件中的kv 部分相同**

在.py中:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout

class MyLayout(BoxLayout):
    pass
class TutorialApp(App):  
#the kv file name will be Tutorial (name is before the "App")
    def build(self):
        return MyLayout()
TutorialApp().run()
 

在Tutorial.kv中:

<MyLayout> # no need to import stuff in kv!
    orientation:"vertical"
    Label:
        id:mylabel
        text:"My App"
    Button:
        text: "Click me!"
        on_press: print(mylabel.text)
 

**示例7:链接到特定的kv文件+在python中接收label.text **

在.py中:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout

class MyLayout(BoxLayout):
    def printMe(self_xx, yy):
        print(yy)
class TutorialApp(App): 
    def build(self):
        self.load_kv('myapp.kv')
        return MyLayout()
TutorialApp().run()
 

在myapp.kv中:orientation:“vertical”标签:id:mylabel text:“我的应用程序”按钮:文字:“点击我!” on_press:root.printMe(mylabel.text)

例8:按钮打印标签的文本(使用ids (“ID”)在python中使用def)

请注意:

  • 示例7中的self_xxself 替换

在.py中:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout

class MyLayout(BoxLayout):
    def printMe(self):
        print(self.ids.mylabel.text)
class TutorialApp(App):
    def build(self):
        self.load_kv('myapp.kv')
        return MyLayout()
TutorialApp().run()
 

在myapp.kv中:

<MyLayout>
    orientation:"vertical"
    Label:
        id:mylabel
        text:"My App"
    Button:
        text: "Click me!"
        on_press: root.printMe()
 

例9:按钮打印标签的文本(使用StringProperty在python中使用def)

在.py中:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
class MyLayout(BoxLayout):
    stringProperty_mylabel= StringProperty("My App")
    def printMe(self):
        print(self.stringProperty_mylabel)

class TutorialApp(App):
    def build(self):
        return MyLayout()
TutorialApp().run()
 

在Tutorial.kv中:

<MyLayout>
    orientation:"vertical"
    Label:
        id:mylabel
        text:root.stringProperty_mylabel
    Button:
        text: "Click me!"
        on_press: root.printMe()
 

示例10:按钮打印标签的文本(使用ObjectProperty在python中使用def)

在.py中:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
class MyLayout(BoxLayout):
    objectProperty_mylabel= ObjectProperty(None)
    def printMe(self):
        print(self.objectProperty_mylabel.text)

class TutorialApp(App):
    def build(self):
        return MyLayout()
TutorialApp().run()
 

在Tutorial.kv中:

<MyLayout>
    orientation:"vertical"
    objectProperty_mylabel:mylabel
    Label:
        id:mylabel
        text:"My App"
    Button:
        text: "Click me!"
        on_press: root.printMe()
 

你好世界在kivy。

以下代码说明如何在kivy中制作“hello world”应用程序。要在ios和android中运行此应用程序,请将其另存为main.py并使用buildozer。

from kivy.app import App
from kivy.uix.label import Label
from kivy.lang import Builder

Builder.load_string('''
<SimpleLabel>:
    text: 'Hello World'
''')


class SimpleLabel(Label):
    pass


class SampleApp(App):
    def build(self):
        return SimpleLabel()

if __name__ == "__main__":
    SampleApp().run()
 

RecycleView

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.button import Button


items = [
    {"color":(1, 1, 1, 1), "font_size": "20sp", "text": "white",     "input_data": ["some","random","data"]},
    {"color":(.5,1, 1, 1), "font_size": "30sp", "text": "lightblue", "input_data": [1,6,3]},
    {"color":(.5,.5,1, 1), "font_size": "40sp", "text": "blue",      "input_data": [64,16,9]},
    {"color":(.5,.5,.5,1), "font_size": "70sp", "text": "gray",      "input_data": [8766,13,6]},
    {"color":(1,.5,.5, 1), "font_size": "60sp", "text": "orange",    "input_data": [9,4,6]},
    {"color":(1, 1,.5, 1), "font_size": "50sp", "text": "yellow",    "input_data": [852,958,123]}
]


class MyButton(Button):

    def print_data(self,data):
        print(data)


KV = '''

<MyButton>:
    on_release:
        root.print_data(self.input_data)

RecycleView:
    data: []
    viewclass: 'MyButton'
    RecycleBoxLayout:
        default_size_hint: 1, None
        orientation: 'vertical'

'''


class Test(App):
    def build(self):
        root = Builder.load_string(KV)
        root.data = [item for item in items]
        return root


Test().run()
 

Kivy中的简单弹出示例。

以下代码说明了如何使用Kivy进行简单的弹出窗口。

from kivy.app import App
from kivy.uix.popup import Popup
from kivy.lang import Builder
from kivy.uix.button import Button

Builder.load_string('''
<SimpleButton>:
    on_press: self.fire_popup()
<SimplePopup>:
    id:pop
    size_hint: .4, .4
    auto_dismiss: False
    title: 'Hello world!!'
    Button:
        text: 'Click here to dismiss'
        on_press: pop.dismiss()
''')


class SimplePopup(Popup):
    pass

class SimpleButton(Button):
    text = "Fire Popup !"
    def fire_popup(self):
        pops=SimplePopup()
        pops.open()

class SampleApp(App):
    def build(self):
        return SimpleButton()

SampleApp().run()
 

触摸,抓住并移动

以下示例创建一个画面,其中包含2个点和1行。您将能够移动点和线。

from kivy.app import App
from kivy.graphics import Ellipse, Line
from kivy.uix.boxlayout import BoxLayout


class CustomLayout(BoxLayout):

    def __init__(self, **kwargs):
        super(CustomLayout, self).__init__(**kwargs)

        self.canvas_edge = {}
        self.canvas_nodes = {}
        self.nodesize = [25, 25]

        self.grabbed = {}

        #declare a canvas
        with self.canvas.after:
            pass

        self.define_nodes()
        self.canvas.add(self.canvas_nodes[0])
        self.canvas.add(self.canvas_nodes[1])
        self.define_edge()
        self.canvas.add(self.canvas_edge)
    

    def define_nodes(self):
        """define all the node canvas elements as a list"""

        self.canvas_nodes[0] = Ellipse(
            size = self.nodesize,
            pos =  [100,100]
            )

        self.canvas_nodes[1] = Ellipse(
            size = self.nodesize,
            pos =  [200,200]
            )

    def define_edge(self):
        """define an edge canvas elements"""


        self.canvas_edge = Line(
            points =  [
                self.canvas_nodes[0].pos[0] + self.nodesize[0] / 2,
                self.canvas_nodes[0].pos[1] + self.nodesize[1] / 2,
                self.canvas_nodes[1].pos[0] + self.nodesize[0] / 2,
                self.canvas_nodes[1].pos[1] + self.nodesize[1] / 2
                ],
            joint = 'round',
            cap = 'round',
            width = 3
            )


    def on_touch_down(self, touch):

        for key, value in self.canvas_nodes.items():
            if (value.pos[0] - self.nodesize[0]) <= touch.pos[0] <= (value.pos[0] + self.nodesize[0]):
                if (value.pos[1] - self.nodesize[1]) <= touch.pos[1] <= (value.pos[1] + self.nodesize[1]):
                    touch.grab(self)
                    self.grabbed = self.canvas_nodes[key]
                    return True

    def on_touch_move(self, touch):

        if touch.grab_current is self:
            self.grabbed.pos = [touch.pos[0] - self.nodesize[0] / 2, touch.pos[1] - self.nodesize[1] / 2]
            self.canvas.clear()
            self.canvas.add(self.canvas_nodes[0])
            self.canvas.add(self.canvas_nodes[1])
            self.define_edge()
            self.canvas.add(self.canvas_edge)
        else:
            # it's a normal touch
            pass

    def on_touch_up(self, touch):
        if touch.grab_current is self:
            # I receive my grabbed touch, I must ungrab it!
            touch.ungrab(self)
        else:
            # it's a normal touch
            pass

class MainApp(App):

    def build(self):
        root = CustomLayout()
        return root

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