[英]Kivy strange behavior when it updates Image Texture
我正在嘗試使用 OpenCV 圖像更新 Kivy Image.texture,並且我正在使用一個新線程來執行此操作。 我發現了一些關於“圖形操作應該在主線程中”的討論。 但是,我仍然想弄清楚為什么下面的代碼有效。
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.image import Image
from kivy.graphics.texture import Texture
import cv2
from threading import Thread
class MainApp(App):
def __init__(self):
super().__init__()
self.layout = FloatLayout()
self.image = Image()
self.layout.add_widget(self.image)
Thread(target=self.calculate).start()
def build(self):
return self.layout
def calculate(self):
img = cv2.imread("test.png")
w, h = img.shape[1], img.shape[0]
img = cv2.flip(img, flipCode=0)
buf = img.tostring()
texture = Texture(0, 0, 0).create(size=(w, h), colorfmt="bgr")
texture.blit_buffer(buf, colorfmt='bgr', bufferfmt='ubyte')
self.image.texture = texture
def main():
Image(source='test.png') # remove this line will froze the app
MainApp().run()
if __name__ == "__main__":
main()
如果我刪除這一行:
Image(source='test.png')
該應用程序被凍結。 有人可以幫助我理解為什么在主循環外貼上 Image 對象會影響 MainApp 的運行。
不確定為什么該行會影響您的代碼,但主要問題是不僅需要在主線程上完成 GUI 操作,而且任何blit_buffer()
也必須在主線程上完成。 因此,您的代碼的工作版本Image()
刪除了Image()
)如下所示:
from functools import partial
from kivy.app import App
from kivy.clock import Clock
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.image import Image
from kivy.graphics.texture import Texture
import cv2
from threading import Thread
class MainApp(App):
def __init__(self):
super().__init__()
self.layout = FloatLayout()
self.image = Image()
self.layout.add_widget(self.image)
Thread(target=self.calculate).start()
def build(self):
return self.layout
def calculate(self):
img = cv2.imread("test.png")
w, h = img.shape[1], img.shape[0]
img = cv2.flip(img, flipCode=0)
buf = img.tostring()
Clock.schedule_once(partial(self.do_blit, buf, w, h))
def do_blit(self, buf, w, h, dt):
texture = Texture(0, 0, 0).create(size=(w, h), colorfmt="bgr")
texture.blit_buffer(buf, colorfmt='bgr', bufferfmt='ubyte')
self.image.texture = texture
def main():
# Image(source='test.png') # remove this line will froze the app
MainApp().run()
if __name__ == "__main__":
main()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.