python 3.x kivy : dynamically adding widgets to scrollview

标签 python kivy

我是 kivy 的新手,正在尝试创建一个实时填充多个小部件的 ScrollView 。那样的作品.. 但订单项本身经常会丢失自己的小部件,我经常收到此错误:

[CRITICAL] [时钟] 警告,在下一帧之前完成了太多迭代。检查您的代码,或增加 Clock.max_iteration 属性

我读了很多“时钟”,阻塞了主线程等。我尝试使用不同的线程来解决它。但仍然缺少小部件。

附上代码和图片。非常感谢帮助!谢谢!

widgets missing..

我的 Controller .kv

#:kivy 1.0

<Controller>:

    size_hint: 1., 1.
    pos_hint: {'center_x': .5, 'center_y': .5}
    do_default_tab: False


    tab1_pgbar: tab1_pgbar
    layout_content: layout_content
    tab1_refresh_btn: tab1_refresh_btn

    TabbedPanelItem:
        id: tab1
        text: 'Browse'

        BoxLayout:
            id: bl
            orientation: 'vertical'

            ScrollView:
                size_hint: 1.0,0.7              

                GridLayout:
                    id: layout_content
                    size_hint_y: None
                    height: self.minimum_height                
                    cols: 1
                    row_default_height: '100dp'
                    row_force_default: True
                    spacing: 0, 5            

            BoxLayout:
                size_hint: 1.0,None
                height: 25              

                ProgressBar:
                    size_hint: 1.0,1.0  
                    id: tab1_pgbar 
                    max: 1000

                Button:
                    id: tab1_refresh_btn    
                    text: 'Refresh'             
                    size: 100,25
                    on_release: root.refresh()   

我的kivyMain.py

import kivy
kivy.require('1.10.0')

from kivy.uix.boxlayout import BoxLayout
from kivy.app import App
from kivy.properties import ObjectProperty
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.clock import mainthread

import time
import threading


class myJobEntry(BoxLayout):
    def __init__(self):
        super(myJobEntry, self).__init__()       


    def addStuff(self,runindex,program):   
        b1 = Button(text=runindex,size_hint=(None,1.0),width=100)
        b2 = TextInput(text=program,height=80)

        hbox1 = BoxLayout(orientation='horizontal')      
        for i in range(10):
            hbox1.add_widget(Button(text='{}'.format(i)))


        vbox1 = BoxLayout(orientation='vertical')
        vbox1.add_widget(hbox1)
        vbox1.add_widget(b2)

        self.add_widget(b1)
        self.add_widget(vbox1)


class Controller(TabbedPanel):
    '''Create a controller that receives a custom widget from the kv lang file.
    Add an action to be called from the kv lang file.
    '''    
    layout_content = ObjectProperty()
    tab1_refresh_btn = ObjectProperty()
    tab1_pgbar = ObjectProperty() 
    text_input = ObjectProperty() 

    def addSeveralObjects(self):
        self.tab1_pgbar.value = 0
        self.layout_content.enabled=False

        for i in range(100):              
            myObj = myJobEntry()
            myObj.addStuff('{}'.format(i),'i')            
            self.layout_content.add_widget(myObj)                            
            self.updateBar()


    def refresh(self):        
        self.tab1_refresh_btn.enabled = False
        self.tab1_pgbar.value = 1        

        mythread = threading.Thread(target=self.addSeveralObjects)
        mythread.start()        

        self.resetRefreshButton()


    def resetRefreshButton(self):
        self.tab1_refresh_btn.text = 'Last Refresh: {}'.format(time.ctime())
        self.tab1_refresh_btn.enabled = True


    def updateBar(self):
        self.tab1_pgbar.value += 1

class ControllerApp(App):

    def build(self):       
        return Controller()

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

最佳答案

我猜问题是你的线程,更好的选择是使用 kivy Clock 对象:

...
from kivy.clock import Clock
from kivy.properties import NumericProperty
from kivy.metrics import dp
...

class Controller(TabbedPanel):
    '''Create a controller that receives a custom widget from the kv lang file.
    Add an action to be called from the kv lang file.
    '''
    layout_content = ObjectProperty()
    tab1_refresh_btn = ObjectProperty()
    tab1_pgbar = ObjectProperty()
    text_input = ObjectProperty()
    i = 0
    h = NumericProperty(0)

    def addSeveralObjects(self, *args):
        self.layout_content.enabled = False
        myObj = myJobEntry()
        myObj.addStuff('{}'.format(self.i), '{}'.format(self.i))
        self.layout_content.add_widget(myObj)
        if self.i % 4 == 0:
            self.h += dp(420)
        self.updateBar()
        self.i += 1
        if self.i >= 100:
            self.clock.cancel()

    def refresh(self):
        self.tab1_refresh_btn.enabled = False
        self.clock =Clock.schedule_interval(self.addSeveralObjects, .05)
        self.resetRefreshButton()

    def resetRefreshButton(self):
        self.tab1_refresh_btn.text = 'Last Refresh: {}'.format(time.ctime())
        self.tab1_refresh_btn.enabled = True

    def updateBar(self):
        self.tab1_pgbar.value += 1
...

在你的kv中:

<Controller>:
    ...
    TabbedPanelItem:
        ...
        BoxLayout:
            ...
            ScrollView:
                size_hint: 1.0,0.7
                GridLayout:
                    id: layout_content
                    height: root.h
                    size_hint_y: None
                    cols: 1
                    row_default_height: '100dp'
                    row_force_default: True
                    spacing: 0, 5
            ...
        ...
     ...
 ...

关于python 3.x kivy : dynamically adding widgets to scrollview,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47693921/

相关文章:

python-3.x - Kivy - 访问 .kv 文件中 ListProperty 的元素

Python顺序遍历到一个平面列表

python - H2O R API : retrieving optimal model from grid search

python - Pymongo:从数组中删除一个元素

python - 在kivy中设置全局字体大小

python - 是否有内置方法来获取 ToggleButton 组的当前选择?

python - 我可以在 Tensorflow 联合学习 (TFF) 的 keras 模型中使用 class_weight

python - "Can' t convert 'int' object to str implicitly”错误(Python)

android - 适用于 Android 应用的 Kivy

python - 使用类定义的对象不继承颜色属性 Kivy