2016-02-20 60 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