2016-02-20 39 views
2

我对kivy比较新,并且对于某些图像和按钮图像加载不正确时存在间歇性问题,即使相同的图像正确加载其他使用相同图像的小部件也是如此。我认为这是线程和kivy绘图不能很好地协同工作的问题。对于下面的代码重现问题线程是没有必要的,但在完整的应用程序,加载所有的图像块太长。谢谢你的帮助。kivy故障与图像和线程

from kivy.app import App 
from kivy.core.window import Window 
from kivy.properties import ObjectProperty 
from kivy.uix.screenmanager import Screen 

from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.relativelayout import RelativeLayout 
from kivy.uix.floatlayout import FloatLayout 
from kivy.uix.scrollview import ScrollView 
from kivy.effects.opacityscroll import OpacityScrollEffect 

from kivy.uix.textinput import TextInput 
from kivy.uix.button import Button 
from kivy.uix.label import Label 
from kivy.uix.gridlayout import GridLayout 
from kivy.uix.image import AsyncImage, Image 
from kivy.uix.screenmanager import ScreenManager, Screen 

from _functools import partial 
from threading import Thread 


class resultLine(RelativeLayout): 
    def __init__(self, title, coverUrl, showid): 
     super(RelativeLayout, self).__init__(size_hint=(None, None), size=(Window.width * 0.945, 0.12 * Window.height)) 
     self.cover = AsyncImage(source=coverUrl, loading_image='loading.gif', error_image='../../tv.png', 
          size=(0.2 * self.width, 0.85 * self.height), pos=(0, 0.125 * self.height), size_hint=(None, None), 
          nocache=True) 
     self.cover.width = Window.width * 0.2 

     self.nameButton = Button(text='', size=(self.width, self.height), x=0, size_hint=(None, None), opacity=0.85, 
           background_normal='../../button.png', background_down='../../button_pressed.png') 
     fontSize=0.05 * Window.width 
     self.nameTag = Label(text='    ' + title, font_size=fontSize, width=Window.width * 0.945, 
          height=self.height, x=0, y=0.05*self.height, 
          size_hint=(None, None), valign='middle', halign='left', opacity=0.85, 
          padding_x=Window.width * 0.025) 

     self.nameTag.text_size = self.nameTag.size 
     self.nameTag.shorten = True 
     self.nameTag.shorten_from = 'right' 
     self.nameTag.split_str = ' ...' 

     self.nameButton.bind(on_press=self.doNameButtonPress) 
     self.nameButton.bind(on_release=self.doNameButtonRelease) 


     self.add_widget(self.nameButton)   
     self.add_widget(self.nameTag) 
     self.add_widget(self.cover) 
     self._trigger_layout() 

    def doNameButtonPress(self, instance): 
     self.nameTag.x += 0.01 * self.width 
     self.nameTag.y -= 0.1 * self.height 
     # self.cover.pos_hint = {'x':0.01, 'y':0.025} 
     self.cover.x += 0.01 * self.width 
     self.cover.y -= 0.1 * self.height 

    def doNameButtonRelease(self, instance): 
     self.nameTag.x -= 0.01 * self.width 
     self.nameTag.y += 0.1 * self.height 
     # self.cover.pos_hint = {'x':0, 'y':0.1} 
     self.cover.x -= 0.01 * self.width 
     self.cover.y += 0.1 * self.height 


class ShowSelector(Screen): 

    bottomLayout = ScrollView(size=(0.95 * Window.width, Window.size[1] * 0.875), pos=(0.025 * Window.width, 0), 
          size_hint=(None, None), bar_margin=-0.0125 * Window.width, effect_cls=OpacityScrollEffect) 
    scrollLayout = GridLayout(cols=1, size_hint=(None, None), height=Window.height, spacing=Window.height * .01) 

    def __init__(self, **kwargs): 

     super(Screen, self).__init__(**kwargs) 
     self.add_widget(self.bottomLayout) 
     self.bottomLayout.add_widget(self.scrollLayout) 

     self.scrollLayout.bind(minimum_height=self.scrollLayout.setter('height')) 

     self.scrollLayout.height = (Window.height * 0.12 + self.scrollLayout.spacing[1]) * 100 

     Thread(target=self.action).start() 

    def action(self): 
     for i in xrange(1,100): 
      self.scrollLayout.add_widget(resultLine(str(i), '1.jpg', 0)) 

class theApp(App): 

    smMain =ScreenManager() 
    selectorScreen = ShowSelector(name='showsel') 

    def build(self): 

     self.smMain.add_widget(self.selectorScreen) 
     return self.smMain 

thisApp=theApp() 
thisApp.run() 

回答

3

我想通了。以防其他人遇到这个问题。对GUI的任何更改都必须在主线程中完成。您可以通过将@mainthread放在函数定义上方的行上来强制执行一个函数。例如:

from kivy.clock import mainthread 

@mainthread 
def add something(self, w): 
    self.add_widget(w) 

您必须“导入mainthread”才能正常工作。

+0

你能解释“import mainthread”是什么意思吗? – mkrinblk

+0

我的意思是所有进口的顶部你必须加 'from kivy.clock import mainthread' – dude8604

+0

来自kivy.clock模块? – mkrinblk