2014-10-13 4 views
0

у меня есть:Изменение файла PySide.QtGui.QListWidget с испускаемым сигналом от многопроцессорного вызова. Асинхронный вызов по сети приводит к ошибке Runtime?

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, что для того, чтобы изменить графический интерфейс из вторичного потока выполнения, нужно использовать механизм слот-сигнала, который является то, что я сделал в MyClass, хотя, когда я называю do_some_async_computation Я хотел бы ожидать бассейн, чтобы инициировать вторичный поток для some_computation функции ..which происходит, после того, как вычисление закончило my_callback_fct выполняется соответствующим образом, который излучает my_signal сигнала, который подключается к on_my_signal слот, который выполняется, как и ожидалось, но когда изменения self.mylistwidget это дает Runtime Error/QWidget runtime error redundant repaint detected

+0

Думаю, вам придется включить здесь достаточно кода, чтобы воспроизвести проблему. Если я создаю свою собственную примерную программу, используя только то, что вы предоставили, вызов 'mylistwidget.clear()' действительно работает нормально. – dano

+0

Как обрабатывается объект Result-object apply_async? В приведенном выше коде my_callback_fct никогда не вызывался. – deets

+0

@deets 'my_callback_fct' вызывается автоматически, когда' some_comput' завершается (пока он не генерирует исключение). – dano

ответ

0

Я решил это, используя 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) 
     # ... 

Он работает как шарм.

+0

@ andrew-g-h * лицоpalm * Jup. Вам, конечно, нужен QThread. Я даже сказал это сам, но не подключил точки ... – deets

1

Я не наблюдаемую фактическую ошибку, но в подобном случае мы используем QueuedConnection для обеспечения правильного прохождения сигнала от одного потока к другому. Это делается автоматически для некоторых людей, если объекты, о которых идет речь, принадлежат к различным потокам (QObject имеет понятие QThread, которое им владеет). Но в вашем случае все делается на одном объекте, поэтому Qt не может знать. Есть

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

Нет, все еще падает. Я добавил часть своего исходного кода. –