2012-01-27 2 views
2

単純なチャットプログラムの場合、私はboost :: pythonでラップされたc libを使用します。QThreadブロックをブロックするGUI

PyQTを使用して簡単なGUIを作成します。メッセージを受信するには、 libへのブロッキングコールを介して行われます。 GUIが独立してリフレッシュするために、通信部分はQThreadにあります。

私は独立しているようにGUIとの通信を前提となりますが、GUIは非常に応答しないとメッセージが入って来ているときにのみ更新するようだ。

#!/usr/bin/env python 

import sys 

from PyQt4.QtCore import * 
from PyQt4.QtGui import * 

import pynetcom2 
import time 


class NetCom(QThread): 

    def __init__(self): 
    QThread.__init__(self) 
    self.client = pynetcom2.Client() 
    self.client.init('127.0.0.1', 4028) 
    self.client.provide('myChat', 1) 
    self.client.subscribe('myChat', 100) 

    def run(self): 
    while (1): 
     print "Waiting for message..." 
     text = self.client.recvStr('myChat', True) 
    return 



class Netchat(QMainWindow): 

    def __init__(self, argv): 

     if (len(argv) != 2): 
      print "Usage: %s <nickname>" %(argv[0]) 
      sys.exit(1) 
     self.nickname = argv[1] 
     print "Logging in with nickname '%s'" %(self.nickname) 

     super(Netchat, self).__init__() 
     self.setupUI() 

     rect = QApplication.desktop().availableGeometry() 
     self.resize(int(rect.width() * 0.3), int(rect.height() * 0.6)) 
     self.show() 

     self.com = NetCom() 
     self.com.start() 

    def setupUI(self): 
     centralWidget = QWidget() 
     self.setCentralWidget(centralWidget) 

     self.testList = QListWidget() 

     mainLayout = QHBoxLayout() 
     mainLayout.addWidget(self.testList) 
     centralWidget.setLayout(mainLayout) 

if __name__ == "__main__": 
    app = QApplication(sys.argv) 
    netchat = Netchat(sys.argv) 
    app.exec_() 

答えて

6

これは悪名高いグローバルインタープリタロックが原因である可能性があり(GIL)。 Pythonでは、2つのスレッドが同時にPythonコードを実行することはできません。あなたのCコードでは、GUIコードを並行して実行させたい場合は、GILを明示的にリリースして再取得する必要があります。

これは、Python C APIのマニュアルで説明されています。Thread State and the Global Interpreter Lock

それはあなたのCの拡張に次のマクロを使用することに沸く:十分

Py_BEGIN_ALLOW_THREADS 

// Your expensive computation goes here. 

Py_END_ALLOW_THREADS 
+0

悪名高いわけではありません。)今作品の魅力のように! – joekr

関連する問題