PysideのQProgressDialogを、別スレッドで実行させたいです。


表題の通り、QProgressDialogを別スレッドで実行したいのですが、安定せずに困っています。  
サードパーティ製の重い処理を実行させつつ、ダイアログが固まらないようにしたいです。  
やりたいことは、基本は次のようなスクリプトです。  
(サードパーティ製モジュールの入る部分はコメントアウトしてあります)

[code]

    # -*- coding: utf-8 -*-
    import sys
    from PySide import QtCore, QtGui
    import time
    # import third_party_module
    
    
    def start_third_party_module():
        item_num = 3
    
        d=QtGui.QProgressDialog()
        d.setRange(0, item_num)
        d.show()
    
        for i in range(item_num):
            # ここに、重い処理が入る
            # third_party_module.do(i)
            d.setValue(i)
            print i
            time.sleep(2)
    
    class MainWindow(QtGui.QMainWindow):
        def __init__(self, parent=None):
            super(MainWindow, self).__init__()
            button = QtGui.QPushButton(self)
            button.setText("Click me")
            button.clicked.connect(self.pushBtn)
    
        def pushBtn(self):
            start_third_party_module()
    
    def main():
        qApp = QtGui.QApplication(sys.argv)
        win = MainWindow(qApp)
        win.show()
        sys.exit(qApp.exec_())
    
    main()
    
[/code]

上記スクリプトを実行させると、一応ダイアログは表示されますがcancelボタンが押せないなど都合が悪いです。  
サードパーティ製のモジュールをQThreadで実行することも試してみたのですが安定せず(頻繁に落ちる)、メインの中でサードパーティ製のモジュールを実行させつつ、プログレスダイアログにも触れるようにしたいと思っております。

どうかお力添えをお願いいたします。

追記：上記スクリプトが、前回は端折りすぎていたので、情報を追記しました。  
よろしくお願いいたします。




重い処理のせいではなく、`QProgressDialog`の表示方法の問題と思います。  
具体的には、`MainWindow.pushBtn`以降で一連の処理をさせているのが原因と思います。

2か所変更すると、`QProgressDialog`の表示更新と操作が可能になると思います。(重い処理をさせつつ)

  1. `button`のconnect方法。  
以下のように変更する。

[code]         # 変更前

        button.clicked.connect(self.pushBtn)
        # 変更後
        button.clicked.connect(self.pushBtn, QtCore.Qt.QueuedConnection)
    
[/code]

  2. `dialog`の表示方法。  
`pushBtn`以降の処理で表示させるのではなく、その外で表示させるようにする。  
具体的には、`QProgressDialog`オブジェクトを`MainWindow`のメンバとし、`button.clicked`にconnectして表示させるようにする。

[code]         # 変更後(MainWindow.__init__内)

        self.dialog = QProgressDialog()
        button.clicked.connect(dialog.show)
    
[/code]

原因は、`button.clicked`のイベントで一連の処理(`MainWindow.pushBtn`以降の処理)を行っているため、イベントディスパッチャに処理が戻らないためです。(戻らないと他のイベントが処理されない)  
ですので、`button.clicked`のイベントをイベントキューに入れるようの動作させるために前者の変更を行います。  
同様に`QtGui.QProgressDialog`でイベントディスパッチできるよう、後者の変更を行います。

＃connectの第2引数については、[`Qt.ConnectionType`のドキュメント](https://srinikom.github.io/pyside-
docs/PySide/QtCore/Qt.html#PySide.QtCore.PySide.QtCore.Qt.ConnectionType)を参照ください。

