第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

如果從線程啟動(dòng),QMovie 不會(huì)啟動(dòng)

如果從線程啟動(dòng),QMovie 不會(huì)啟動(dòng)

藍(lán)山帝景 2023-08-22 15:51:42
各位開(kāi)發(fā)者!我有一個(gè)關(guān)于 Qt 和多線程的問(wèn)題。=== 簡(jiǎn)短版本 =============================================Qt 可以做我想做的事嗎?即(1)顯示一個(gè)加載器;(2)在后臺(tái)下載gif;(3) 下載后在主窗口中顯示下載的gif?===長(zhǎng)版==============================================我有一個(gè)想法,當(dāng)我按下按鈕時(shí),它:顯示裝載機(jī);激活一個(gè)從網(wǎng)絡(luò)下載 gif 的線程;用下載的 gif 替換主窗口中隱藏的默認(rèn) gif 并顯示它隱藏裝載機(jī);我遇到的問(wèn)題是,當(dāng)顯示下載的 gif 時(shí),它被“凍結(jié)”或僅顯示第一幀。除此之外一切都很好。然而,它需要在隱藏加載器后將 gif 動(dòng)畫(huà)化。這里提到的是所以Qt事件循環(huán)負(fù)責(zé)執(zhí)行你的代碼以響應(yīng)程序中發(fā)生的各種事情,但是當(dāng)它執(zhí)行你的代碼時(shí),它不能做任何其他事情。我相信這是問(wèn)題的核心。還建議建議在 Qt 中使用 QThread 而不是 Python 線程,但如果您不需要從函數(shù)與主線程通信,則 Python 線程可以正常工作。由于我的線程替換了默認(rèn) gif 的內(nèi)容,我相信它確實(shí)進(jìn)行了通信:(
查看完整描述

2 回答

?
哆啦的時(shí)光機(jī)

TA貢獻(xiàn)1779條經(jīng)驗(yàn) 獲得超6個(gè)贊

除了不應(yīng)在 Qt 主線程之外訪問(wèn)或創(chuàng)建任何 UI 元素這一事實(shí)之外,這對(duì)于使用在其他線程中創(chuàng)建的對(duì)象的 UI 元素也有效。


在您的具體情況下,這不僅意味著您無(wú)法在單獨(dú)的線程中設(shè)置影片,而且也無(wú)法在那里創(chuàng)建 QMovie。


在下面的示例中,我打開(kāi)一個(gè)本地文件,并使用信號(hào)將數(shù)據(jù)發(fā)送到主線程。從那里,我創(chuàng)建一個(gè) QBuffer 將數(shù)據(jù)存儲(chǔ)在 QMovie 可以使用的 IO 設(shè)備中。請(qǐng)注意,緩沖區(qū)和電影都必須有持久引用,否則函數(shù)返回后它們將被垃圾回收。


from PyQt5.QtCore import QThread, QByteArray, QBuffer


class ChangeGif(QThread):

    dataLoaded = pyqtSignal(QByteArray)

    def __init__(self, all_widgets):

        QThread.__init__(self)

        self.all = all_widgets


    def run(self):

        sleep(1)

        f = QFile('new.gif')

        f.open(f.ReadOnly)

        self.dataLoaded.emit(f.readAll())

        f.close()



class MainWindow(QWidget):

    # ...

    def change_gif(self):

        self.loader_label.show()

        self.worker = ChangeGif(self)

        self.worker.dataLoaded.connect(self.applyNewGif)

        self.worker.start()


    def applyNewGif(self, data):

        # a persistent reference must be kept for both the buffer and the movie, 

        # otherwise they will be garbage collected, causing the program to 

        # freeze or crash

        self.buffer = QBuffer()

        self.buffer.setData(data)

        self.newGif = QMovie()

        self.newGif.setCacheMode(self.newGif.CacheAll)

        self.newGif.setDevice(self.buffer)

        self.gif_label.setMovie(self.newGif)

        self.newGif.start()

        self.gif_label.show()

        self.loader_label.hide()

請(qǐng)注意,上面的示例僅用于解釋目的,因?yàn)橄螺d過(guò)程可以使用 QtNetwork 模塊完成,該模塊異步工作并提供簡(jiǎn)單的信號(hào)和插槽來(lái)下載遠(yuǎn)程數(shù)據(jù):


from PyQt5.QtCore import QUrl

from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest


class MainWindow(QWidget):

    def __init__(self):

        # ...

        self.downloader = QNetworkAccessManager()


    def change_gif(self):

        self.loader_label.show()

        url = QUrl('https://path.to/animation.gif')

        self.device = self.downloader.get(QNetworkRequest(url))

        self.device.finished.connect(self.applyNewGif)


    def applyNewGif(self):

        self.loader_label.hide()

        self.newGif = QMovie()

        self.newGif.setDevice(self.device)

        self.gif_label.setMovie(self.newGif)

        self.newGif.start()

        self.gif_label.show()


查看完整回答
反對(duì) 回復(fù) 2023-08-22
?
繁華開(kāi)滿天機(jī)

TA貢獻(xiàn)1816條經(jīng)驗(yàn) 獲得超4個(gè)贊

使用 Qt 的主要規(guī)則是只有一個(gè)主線程負(fù)責(zé)操作 UI 小部件。它通常被稱為GUI thread。您永遠(yuǎn)不應(yīng)該嘗試從其他線程訪問(wèn)小部件。例如,Qt 計(jì)時(shí)器不會(huì)從另一個(gè)線程開(kāi)始激活,并且 Qt 會(huì)在運(yùn)行時(shí)控制臺(tái)中打印警告。在你的情況下 - 如果你把 QMovie 的所有操作都放在 GUI 線程中,很可能一切都會(huì)按預(yù)期工作。

該怎么辦?使用信號(hào)和槽 - 它們也被設(shè)計(jì)為在線程之間工作。

你的代碼應(yīng)該做什么:

  1. 從主線程顯示加載程序。

  2. 激活從網(wǎng)絡(luò)下載 gif 的線程。

  3. 下載準(zhǔn)備就緒后 -GUI thread'. Remember to use 在連接信號(hào)和插槽時(shí)發(fā)出信號(hào)并在主 Qt::QueuedConnection` 中捕獲它,盡管在某些情況下會(huì)自動(dòng)使用它。

  4. 在接收槽中,將主窗口中的默認(rèn) gif 替換為下載的 gif,并顯示它并隱藏加載程序。

您必須使用某種同步機(jī)制來(lái)避免數(shù)據(jù)競(jìng)爭(zhēng)。一個(gè)互斥體就足夠了?;蛘吣梢詫?shù)據(jù)作為信號(hào)槽參數(shù)傳遞,但如果是 gif,它可能會(huì)太大。


查看完整回答
反對(duì) 回復(fù) 2023-08-22
  • 2 回答
  • 0 關(guān)注
  • 1706 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)