如何动态地将在python代码中创建的小部件添加到kv文件中

时间:2017-05-03 18:20:15

标签: python python-2.7 user-interface kivy

我是Kivy的新手,我遇到了向gridLayout添加项目的问题。这些项目是在我的python类中创建的,我想在我的kv文件中填充gridlayout。它有效,但标签被添加到同一个地方(这意味着它们不在列中 - 它们都在一个单元格中)。我已尝试过here的解决方案,但我仍然不知道错误。

KV档案:

#:kivy 1.9.1

<Connected>:

    BoxLayout:
        orientation: 'vertical'

        Label:
            text: 'main window'
            font_size: 32

        BoxLayout:
            orientation: 'vertical'

            Label:
                text: 'Flights'
                font_size: 32

            BoxLayout:
                orientation: 'horizontal'
                Label:
                    text: 'From'
                    font_size: 32
                Label:
                    text: 'To'
                    font_size: 32
                Label:
                    text: 'Company'
                    font_size: 32
                Label:
                    text: 'Date'
                    font_size: 32

            ScrollView:
                size_hint_y: None
                height: '200dp'

                GridLayout:
                    id: flights_table
                    col: 4
                    size_hint_y: None
                    spacing: '1dp'

            Button:
                text: "Buy a ticket"
                font_size: 32
                on_press: root.order_flight()

            Button:
                text: "Logout"
                font_size: 24
                on_press: root.disconnect()

Python代码:

# coding: utf-8
import json
import requests
from kivy.adapters.dictadapter import (
    DictAdapter,
    ListAdapter,
)
from kivy.properties import (
    ListProperty,
    ObjectProperty,
)
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.screenmanager import (
    Screen,
    SlideTransition,
)
from kivy.uix.listview import ListItemButton


class Connected(Screen):
    u"""Screen after login in."""

    flights = ListProperty()

    def on_pre_enter(self, *args):
        u"""Method that loads before the screen is loaded."""
        self.flights = self.get_flights()

        for flight in self.flights:
            for value in [flight.get('from_city'), flight.get('to_city'), flight.get('company'), flight.get('flight_date')]:
                self.ids.flights_table.add_widget(Label(text=value))

    def disconnect(self):
        u"""Logout method."""
        self.manager.transition = SlideTransition(direction="right")
        self.manager.current = 'login'
        self.manager.get_screen('login').resetForm()

    def get_flights(self):
        u"""Method that gets the flights from a rest api."""
        response = requests.get('http://127.0.0.1:8000/flights/', params={'format': 'json'})
        if response.status_code == 200:
            data = None
            try:
                data = json.loads(response.content.decode('utf-8'))
            except ValueError as err:
                raise
            return data
        return list()

1 个答案:

答案 0 :(得分:1)

我的问题已经解决了。我改变了构建gridlayout的方式。而是在我的.kv文件中构建网格,我得到了我的ScrollView的id并添加了一个gridlayout。 Kivy的警告对我有所帮助:

  

[警告] 0x7ff7ac893a60处的kivy.uix.gridlayout.GridLayout对象没有设置cols或row,也没有触发布局。

此外Kivy documentation给了我一个提示。

所以我的代码现在是这样的:

.kv文件:

#:kivy 1.9.1

<Connected>:

    BoxLayout:
        orientation: 'vertical'

        Label:
            text: 'Main panel'
            font_size: 32

        BoxLayout:
            orientation: 'vertical'

            Label:
                text: 'Flights'
                font_size: 32

            BoxLayout:
                orientation: 'horizontal'
                Label:
                    text: 'From'
                    font_size: 32
                Label:
                    text: 'To'
                    font_size: 32
                Label:
                    text: 'company'
                    font_size: 32
                Label:
                    text: 'Data'
                    font_size: 32

            ScrollView:
                id: scroll_view
                size_hint_y: None
                height: '200dp'


            Button:
                text: "Order a ticket"
                font_size: 32
                on_press: root.order_flight()

            Button:
                text: "Logout"
                font_size: 24
                on_press: root.disconnect()

Python代码:

# coding: utf-8
import json
import requests
from kivy.adapters.dictadapter import (
    DictAdapter,
    ListAdapter,
)
from kivy.properties import (
    ListProperty,
    ObjectProperty,
)
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.screenmanager import (
    Screen,
    SlideTransition,
)
from kivy.uix.listview import ListItemButton
from requests.exceptions import ConnectionError

class Connected(Screen):
    u"""Screen after login in."""

    flights = ListProperty()

    def on_pre_enter(self, *args):
        u"""Method that loads before the screen is loaded."""
        self.flights = self.get_flights()

        scroll = self.ids.scroll_view
        scroll.clear_widgets()
        grid = GridLayout(cols=4, size_hint_y=None, spacing='1dp')
        # grid.bind(minimum_height=grid.setter('height'))
        for flight in self.flights:
            for value in [flight.get('from_city'), flight.get('to_city'), flight.get('company'), flight.get('flight_date')]:
                grid.add_widget(Label(text=value))
        scroll.add_widget(grid)

    def disconnect(self):
        u"""Logout method."""
        self.manager.transition = SlideTransition(direction="right")
        self.manager.current = 'login'
        self.manager.get_screen('login').resetForm()

    def get_flights(self):
        u"""Method that gets the flights from a rest api."""
        try:
            response = requests.get('http://127.0.0.1:8000/flights/', params={'format': 'json'})
        except ConnectionError:
            raise
        if response.status_code == 200:
            data = None
            try:
                data = json.loads(response.content.decode('utf-8'))
            except ValueError as err:
                raise
            return data
        return list()