Kivy: Как я могу применить ScrollView, который я создал в своем файле KV, к Аккордеону, который я сделал в моем файле Python - PullRequest
0 голосов
/ 05 апреля 2020

Я создал Accordion в Python, потому что количество AccordionItems зависит от количества строк в текстовом файле, и я создал скролл-просмотр в своем KV-файле. Как применить скролл-просмотр к Аккордеону, чтобы я мог прокрутить Аккордеон вниз, а не кнопку, которую я сделал в KV?

Должен ли я сделать весь мой код Python сбоку, чтобы он работал, или я могу сделать часть этого в Python и KV и каким-то образом соединить оба вместе?

*. Py

#imported from kivy framework
from kivy.app import App
from kivymd.app import MDApp
from kivy.app import App
from kivy.uix.label import Label
from datetime import datetime
from datetime import timedelta
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import StringProperty,ObjectProperty
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.image import Image
import dictionaryData
from kivy.lang import Builder
from kivy.base import runTouchApp
import os
from kivy.uix.button import Button
from kivy.uix.accordion import Accordion, AccordionItem
from kivy.uix.scrollview import ScrollView
from kivy.core.window import Window
from kivy.app import runTouchApp



class Main_Screen(Screen):

    random_number = StringProperty()

    def __init__(self, **kwargs):
        super(Main_Screen, self).__init__(**kwargs)
        pass

class Dictionary_Screen(Screen):
    layout = ObjectProperty(None)
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        layout = BoxLayout(orientation='vertical')    #instantiate BoxLayout
        self.add_widget(layout)    #add BoxLayout to screen

        file1 = open('dict.txt','r')

        accordion = Accordion(orientation='vertical')    # instantiate Accordion
        layout.add_widget(accordion)    # add Accordion to BoxLayout

        for lines in file1:
            fields = lines.split(',')
            #   Tuple unpacking
            Data = (fields[0], fields[1])
            Title,Description = Data
            print(Title,Description)
            item = AccordionItem(title=Title)
            item.add_widget(Label(text=Description, color=(0,0,0,1)))
            accordion.add_widget(item)    # add AccordionItem to Accordion

#class for all screens
class ScreenManagement(ScreenManager):
   pass

class MainApp(MDApp):
    def build(self):
       # declaring time from python, and making it refresh every second
        self.now = datetime.now()
        Clock.schedule_interval(self.update_clock, 1)

    def update_clock(self, *args):
        self.now = self.now + timedelta(seconds=1)
        self.root.get_screen("Main_Screen").ids["CurrentTime"].text = self.now.strftime("%H:%M:%S")

MainApp().run()

*. KV

#:kivy 1.0
#:import hex kivy.utils.get_color_from_hex
#styles that will apply to all intences for each tag
<MDRaisedButton>:
    font_size:18
#declaring screen managers and printing them in this order
ScreenManagement:
    Main_Screen:
        name: "Main_Screen"
    Dictionary_Screen:
        name: "Dictionary_Screen"
<Main_Screen>:
    FloatLayout:
        spacing: 10
        canvas.before:
            Color:
                rgba: hex('#eff3fa')
            Rectangle:
                size: self.size
                pos: self.pos
        #Navbar
        MDToolbar:
            id: fb
            pos_hint: {'center_x': 0.5, 'top':1.0}
            size_hint_y:None
            height: 50
            title: "Virtual Assistant"
            md_bg_color: hex('#132843')
            Label:
                id: CurrentTime
                font_size:18
                size_hint_x: .1
                color: (1,1,1,1)
        BoxLayout:
            orientation: 'vertical'
            spacing: 10
            padding: 50
            canvas.before:
                Color:
                    rgba: hex('#000')
                Rectangle:
                    size: self.size
                    pos: self.pos
            pos_hint: {'center_x': 0.5, 'center_y': 0.5}
            size_hint: 0.5, 0.5
            Button:
                text: "Dictionary"
                on_release:
                    app.root.current = "Dictionary_Screen"
            Label:
                id: label1
                text: root.random_number
                color:(1,0,1,1)
<Dictionary_Screen>:
    name: "Dictionary_Screen"
    view: view
    ScrollView:
        size_hint: 1, .1
        # setting the width of the scrollbar to 50pixels
        bar_width: 50
        # setting the color of the active bar using rgba
        bar_color: 5, 10, 15, .8
        # setting the color of the inactive bar using rgba
        bar_inactive_color: 5, 20, 10, .5
        # setting the content only to scroll via bar, not content
        scroll_type: ['bars']
        GridLayout:
            id:view
            size_hint_y: None
            cols: 1
            minimum_height: self.height
            Button:
                text:"back"
                on_release: app.root.current = "Main_Screen"





*. Txt

CPU,CPU_INFORMATION
RAM,RAM_INFORMATION
SOMETHING,SOMETHING_INFORMATION
SOMETHING,SOMETHING_INFORMATION
SOMETHING,SOMETHING_INFORMATION
SOMETHING,SOMETHING_INFORMATION
SOMETHING,SOMETHING_INFORMATION
SOMETHING,SOMETHING_INFORMATION
SOMETHING,SOMETHING_INFORMATION
SOMETHING,SOMETHING_INFORMATION
SOMETHING,SOMETHING_INFORMATION
SOMETHING,SOMETHING_INFORMATION

1 Ответ

0 голосов
/ 05 апреля 2020

Когда вы используете ScrollView, вы должны позволить, чтобы его дочерний элемент был больше самого ScrollView. Вот моя модифицированная версия вашего кода с некоторыми изменениями:

#imported from kivy framework
from kivymd.app import MDApp
from kivy.uix.label import Label
from datetime import datetime
from datetime import timedelta
from kivy.clock import Clock
from kivy.properties import StringProperty,ObjectProperty
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.uix.accordion import Accordion, AccordionItem



class Main_Screen(Screen):

    random_number = StringProperty()

    def __init__(self, **kwargs):
        super(Main_Screen, self).__init__(**kwargs)
        pass

class Dictionary_Screen(Screen):
    layout = ObjectProperty(None)
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.accordion = None


    def on_enter(self, *args):

        file1 = open('dict.txt','r')

        if self.accordion is None:
            self.accordion = Accordion(orientation='vertical', size_hint=(1,None), height=150)    # instantiate Accordion
            self.ids.view.add_widget(self.accordion)  # add Accordion to GridLayout
        else:
            self.accordion.clear_widgets()  # clear out all the AccordionItems
            self.accordion.height = 150  # set a starting height (to account for the expanded height of an item)

        item_height = 40  # height to use for each AccordionItem
        for lines in file1:
            fields = lines.split(',')
            #   Tuple unpacking
            Data = (fields[0], fields[1])
            Title,Description = Data
            print(Title,Description)
            item = AccordionItem(title=Title)
            item.add_widget(Label(text=Description, color=(0,0,0,1), size_hint=(1, None), height=item_height))
            self.accordion.height += item_height  # increase Accordion height for his item
            self.accordion.add_widget(item)    # add AccordionItem to Accordion

#class for all screens
class ScreenManagement(ScreenManager):
   pass

kv = '''
#:kivy 1.0
#:import hex kivy.utils.get_color_from_hex
#styles that will apply to all intences for each tag
<MDRaisedButton>:
    font_size:18
#declaring screen managers and printing them in this order
ScreenManagement:
    Main_Screen:
        name: "Main_Screen"
    Dictionary_Screen:
        name: "Dictionary_Screen"
<Main_Screen>:
    FloatLayout:
        spacing: 10
        canvas.before:
            Color:
                rgba: hex('#eff3fa')
            Rectangle:
                size: self.size
                pos: self.pos
        #Navbar
        MDToolbar:
            id: fb
            pos_hint: {'center_x': 0.5, 'top':1.0}
            size_hint_y:None
            height: 50
            title: "Virtual Assistant"
            md_bg_color: hex('#132843')
            Label:
                id: CurrentTime
                font_size:18
                size_hint_x: .1
                color: (1,1,1,1)
        BoxLayout:
            orientation: 'vertical'
            spacing: 10
            padding: 50
            canvas.before:
                Color:
                    rgba: hex('#000')
                Rectangle:
                    size: self.size
                    pos: self.pos
            pos_hint: {'center_x': 0.5, 'center_y': 0.5}
            size_hint: 0.5, 0.5
            Button:
                text: "Dictionary"
                on_release:
                    app.root.current = "Dictionary_Screen"
            Label:
                id: label1
                text: root.random_number
                color:(1,0,1,1)
<Dictionary_Screen>:
    name: "Dictionary_Screen"
    view: view
    ScrollView:
        # size_hint: 1, 1  # this is the default
        # setting the width of the scrollbar to 50pixels
        bar_width: 50
        # bar_margin: 20
        # setting the color of the active bar using rgba
        bar_color: 5, 10, 15, .8
        # setting the color of the inactive bar using rgba
        bar_inactive_color: 5, 20, 10, .5
        # setting the content only to scroll via bar, not content
        scroll_type: ['bars']
        GridLayout:
            id:view
            size_hint_y: None
            cols: 1
            # minimum_height: self.height
            height: self.minimum_height
            Button:
                text:"back"
                on_release: app.root.current = "Main_Screen"
                size_hint_y: None
                height: self.texture_size[1] + 10


'''
class MainApp(MDApp):
    def build(self):
       # declaring time from python, and making it refresh every second
        self.now = datetime.now()
        Clock.schedule_interval(self.update_clock, 1)
        return Builder.load_string(kv)

    def update_clock(self, *args):
        self.now = self.now + timedelta(seconds=1)
        self.root.get_screen("Main_Screen").ids["CurrentTime"].text = self.now.strftime("%H:%M:%S")

MainApp().run()

Я добавил файл 'kv' в виде строки, просто для собственного удобства. В вашем 'kv', под GridLayout, у вас есть:

minimum_height: self.height

, но это немного назад, оно должно быть:

height: self.minimum_height

Это говорит GridLayout чтобы настроить его высоту на минимум, который будет содержать все его дочерние элементы.

Я переместил код, который создает Accordion, в метод on_enter, чтобы id для GridLayout был доступен (он не готов внутри метода __init__).

Я также исключил BoxLayout как ненужный и установил size_hint для Accordion в (1, one), чтобы я мог установить height из Accordion. Затем я вычисляю height для Accordion на основе количества добавленных к нему AccordionItems.

...