簡體   English   中英

我對 kivy 的線程有問題

[英]I'm having a problem with kivy with threading

我正在開發一個使用 kivy 在 python 中工作的項目,並且我在使用線程“TypeError:無法在主 Kivy 線程之外創建圖形指令”時遇到問題 當我按下按鈕時,出現此錯誤

    def ched(self):
    if self.typ == 0:
        self.VpDone()
        self.pinpu.text = ""
    elif self.typ == 1:
        self.GpDone()
        self.pinpu.text = ""
    elif self.typ == 2:
        self.IpDone()
        self.pinpu.text = ""
def down(self):
    if self.pinpu.text is "":
        self.empty()
    else:
        try:
            self.pintd(self.pinpu.text)
            self.ched()
        except:
            self.ERorr()


def diacloce(self, obj):
    self.dialog.dismiss()

def empty(self):

    self.dialog = MDDialog(
        title="Error",
        text="You cannot download nothingness!",
        buttons=[
            MDFlatButton(text="CANCEL", on_release=self.diacloce)

            ]
        )
    self.dialog.open()



def IpDone(self):

    self.dialog = MDDialog(
        title="Done!",
        text="Image downloaded successfully!",
        buttons=[
            MDFlatButton(text="CANCEL", on_release=self.diacloce)

            ]
        )
    self.dialog.open()
def VpDone(self):

    self.dialog = MDDialog(
        title="Done!",
        text="Video downloaded successfully!",
        buttons=[
            MDFlatButton(text="CANCEL", on_release=self.diacloce)

            ]
        )
    self.dialog.open()
def GpDone(self):

    self.dialog = MDDialog(
        title="Done!",
        text="GIF downloaded successfully!",
        buttons=[
            MDFlatButton(text="CANCEL", on_release=self.diacloce)

            ]
        )
    self.dialog.open()

def ERorr(self):
    self.dialog = MDDialog(
        title="Erorr!",
        text="Error ?\nPerhaps there is a problem with the link or the Internet !",
        buttons=[
            MDFlatButton(text="CANCEL", on_release=self.diacloce)

        ]
    )
    self.dialog.open()

.kv 文件:

    MDRectangleFlatButton:
    text:'Download content'
    pos_hint:{'center_x': 0.5, 'center_y': 0.40}
    theme_text_color:"Hint"
    size_hint:(0.35, 0.08)
    on_release:threading.Thread(target=root.down).start()

解決辦法是什么? 看到了很多解決方案,但是我真的不明白或者我無法實現它們,但是我嘗試了很多解決方案謝謝你的時間

你的代碼:

on_release:threading.Thread(target=root.down).start()

將在新線程(不是主線程)上運行root.down() )。 並且該代碼將嘗試在該新線程上創建一個MDDialog和一個MDFlatButton ,這是不允許的。 如果down()方法及其調用的方法只是創建對話框,就像在您的帖子中一樣,那么您不需要使用threading 只需將kv中的那一行更改為:

on_release: root.down()

如果down()方法是一個長時間運行的方法,它將凍結 GUI 直到它完成。 在這種情況下,請保留:

on_release:threading.Thread(target=root.down).start()

並安排任何修改 GUI 或創建 GUI 小部件以在主線程上運行的東西。 一種簡單的方法是在必須在主線程上運行的任何方法上添加@mainthread裝飾器。 例如:

@mainthread
def empty(self):

    self.dialog = MDDialog(
        title="Error",
        text="You cannot download nothingness!",
        buttons=[
            MDFlatButton(text="CANCEL", on_release=self.diacloce)

            ]
        )
    self.dialog.open()

這將強制empty()方法在主線程上運行(相當於使用Clock.schedule_once()運行它)。 對所有只顯示對話框的方法都可以這樣做。

要記住的關鍵點:

  1. 對 GUI 的更新由 Kivy 主循環執行,該循環在主線程上運行。
  2. 任何由事件觸發的方法(如Button按下)都在主線程上運行,並且 Kivy 主循環必須等到該觸發方法完成(因此保持簡短)。
  3. 在非主線程的線程中運行的方法可能不會修改 GUI(甚至創建 GUI 小部件)。

因此,您應該通過使用小的短期 GUI 修改方法將 GUI 修改與非 GUI 處理區分開來,這些方法除了 GUI 修改之外什么都不做(如您的對話框方法)。 這些 GUI 修改方法可以通過使用Clock.schedule_once()或通過使用@mainthread裝飾 GUI 修改方法然后直接調用這些方法從非 GUI 方法(在其他線程上運行)調用。 請記住,這些方法中的任何一種都只是在主線程上調度對 GUI 修改方法的調用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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