簡體   English   中英

改變PySide.QtGui.QListWidget與從multiprocessing.Pool異步調用發出信號導致運行時錯誤?

[英]Altering PySide.QtGui.QListWidget with an emitted signal from a multiprocessing.Pool async call results in Runtime Error?

我有:

from PySide.QtCore import Signal, QObject
from multiprocessing import Pool

def some_computation():
    pass
    # ..some computations
    return 'result'

class MyClass(QObject):

    my_signal = Signal()

    def __init__(self):
        self.mylistwidget = # ... QListWidget from somewhere

        # bind the signal to my slot
        self.my_signal.connect(self.on_my_signal)

    # this is called after computation thread is finished
    def my_callback_fct(result):
        # ..bla bla
        self.my_signal.emit()

    # this is the function I call
    def do_some_async_computation(self)
        pool = Pool(processes=2)
        pool.apply_async(target=some_computation, callback=my_callback_fct)

    # this is the slot
    def on_my_signal(self):
        self.mylistwidget.clear()

我在stackoverflow周圍讀到,為了從輔助執行線程更改gui,必須使用插槽信號機制,這是我在MyClass中所做的,盡管當我調用do_some_async_computation時,我希望池為some_computation函數啟動輔助線程。 ..發生的情況是,在計算完成之后,將相應執行my_callback_fct ,並發出連接到on_my_signal插槽的my_signal信號,該信號已按預期執行,但是在更改self.mylistwidget時,會給出Runtime Error / QWidget runtime error redundant repaint detected

我沒有觀察到您的實際錯誤,但是在類似的情況下,我們使用QueuedConnection來確保信號從一個線程正確傳遞到另一個線程。 如果有問題的對象屬於不同的線程(QObject擁有它們的QThread的概念),那么對於某些人來說,這是自動完成的。 但是在您的情況下,所有操作都在一個對象上完成,因此Qt無法知道。

from PyQt5.QtCore import Qt
...
self.my_signal.connect(self.on_my_signal, Qt.QueuedConnection)

我通過使用QtCore.QThread而不是multiprocessing.Pool解決了這個問題。 我在考慮您談論@deets的機制,我對自己說,為了使Qt.QueuedConnection起作用,它應該在同一上下文中,所以這就是為什么我想使用QThread的原因

class MyComputationalThread(PySide.QtCore.QThread):

    data_available = PySide.QtCore.Signal(str)
    def run(self):
        result = # ... do computations
        serialized_result = json.dumps(result) #  actually I use JSONEncoder here
        self.data_available.emit(serialized_result)

...在我的MyClass

class MyClass(QObject):
    # ...
    mythread = MyComputationalThread()
    # ...

    def __init__(self):
        # ...
        self.mythread.connect(do_something_with_serialized_data, PySide.QtCore.Qt.QueuedConnection)
        # ...

它像一種魅力。

暫無
暫無

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

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