最近中文字幕高清中文字幕无,亚洲欧美高清一区二区三区,一本色道无码道dvd在线观看 ,一个人看的www免费高清中文字幕

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

使用concurrent.futures.ThreadPoolExecutor()時(shí)PyQt5小部件

使用concurrent.futures.ThreadPoolExecutor()時(shí)PyQt5小部件

慕尼黑8549860 2023-12-26 14:40:28
我一直在嘗試使用concurrent.futures.ThreadPoolExecutor()在我的應(yīng)用程序中運(yùn)行一些后臺(tái)任務(wù),以便在這些任務(wù)(“測(cè)量”)運(yùn)行時(shí)我能夠與 GUI 進(jìn)行交互。這些任務(wù)完成后,我分配一個(gè)回調(diào)函數(shù)來更新 GUI 的某些字段,然后嘗試根據(jù)這些字段更新 GUI 小部件(繪圖、表格、列表等)。這是一個(gè)例子:class MainWindow(QtWidgets.QMainWindow):        def __init__(self):        super(MainWindow, self).__init__()        *some more code goes here*        self.executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)    def perform_measurement():        future = self.executor.submit(*a function*)        future.add_done_callback(self.update_gui_fields)    def update_gui_fields(self, future):        data = future.result()        self.items_for_list.append(QStandardItem(data['key']))        *more fields are updated here*        self.QListView1.setModel(self.items_for_list)        *more widgets are updated here*問題是字段已正常更新,但是當(dāng)我嘗試與小部件交互時(shí),應(yīng)用程序崩潰了。這是因?yàn)樽蛹?jí)(此處為)與父級(jí)(此處為)self.items_for_list位于不同的線程中。self.QListView1這是我得到的錯(cuò)誤:QObject: Cannot create children for a parent that is in a different thread.(Parent is QListView(0x555795efbc10), parent's thread is QThread(0x555795296600), current thread is QThread(0x7fd12400a100)QBasicTimer::start: QBasicTimer can only be used with threads started with QThread我在之前的帖子中找不到任何解決方案。知道如何攻擊這個(gè)嗎?謝謝!
查看完整描述

1 回答

?
HUH函數(shù)

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

與 add_done_callback 關(guān)聯(lián)的回調(diào)在輔助線程中執(zhí)行,根據(jù)您的代碼,您正嘗試從該輔助線程更新 GUI,這是禁止的,因此 Qt 會(huì)拋出該警告。解決方案是通過創(chuàng)建一個(gè)通過信號(hào)轉(zhuǎn)發(fā)該信息的 QObject 來實(shí)現(xiàn)邏輯:


import concurrent.futures

import sys

import time


from PyQt5 import QtCore, QtGui, QtWidgets



def measure():

    time.sleep(5)

    return {"key": "value"}



class TaskManager(QtCore.QObject):

    finished = QtCore.pyqtSignal(object)


    def __init__(self, parent=None, max_workers=None):

        super().__init__(parent)

        self._executor = concurrent.futures.ThreadPoolExecutor(max_workers=max_workers)


    @property

    def executor(self):

        return self._executor


    def submit(self, fn, *args, **kwargs):

        future = self.executor.submit(fn, *args, **kwargs)

        future.add_done_callback(self._internal_done_callback)


    def _internal_done_callback(self, future):

        data = future.result()

        self.finished.emit(data)



class MainWindow(QtWidgets.QMainWindow):

    def __init__(self):

        super(MainWindow, self).__init__()

        self.model = QtGui.QStandardItemModel()

        self.view = QtWidgets.QListView()

        self.view.setModel(self.model)


        self.button = QtWidgets.QPushButton("launch")


        self._manager = TaskManager(max_workers=1)

        self._manager.finished.connect(self.update_gui_fields)


        self.button.clicked.connect(self.perform_measurement)


        central_widget = QtWidgets.QWidget()

        self.setCentralWidget(central_widget)

        lay = QtWidgets.QVBoxLayout(central_widget)

        lay.addWidget(self.view)

        lay.addWidget(self.button)


    def perform_measurement(self):

        self._manager.submit(measure)


    def update_gui_fields(self, data):

        self.model.appendRow(QtGui.QStandardItem(data["key"]))



if __name__ == "__main__":


    app = QtWidgets.QApplication(sys.argv)

    w = MainWindow()

    w.show()

    sys.exit(app.exec_())


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

添加回答

舉報(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)