簡體   English   中英

Kivy 更新圖像紋理時的奇怪行為

[英]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 的運行。

“test.png”圖像可以是任何簡單的圖像,如下所示。 您需要將圖像放在與此腳本相同的目錄中。 在此處輸入圖片說明

不確定為什么該行會影響您的代碼,但主要問題是不僅需要在主線程上完成 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM