TCP サーバー用のシンプルな UI を開発しており、サーバーから送信されたログ メッセージで UI を更新する必要がありますが、問題は、そのサーバーへの接続が別のスレッドにあるため、直接触れることができないことです。 UI のウィジェット (再入可能ではないため)。
このテーマに関する記事をいくつか読み、最もエレガントな (そして簡単な) 方法と思われるシグナルを選択しました。
私は次のことをしました:
class Ui_Dialog(QtCore.QObject):
def __init__(self):
super(QtCore.QObject, self).__init__()
def setupUi(self, Dialog):
Dialog.setObjectName(_fromUtf8("Dialog"))
Dialog.resize(800, 580)
self.serverLog = QtGui.QTextEdit(Dialog)
self.serverLog.setGeometry(QtCore.QRect(0, 0, 800, 480))
self.serverLog.setObjectName(_fromUtf8("serverLog"))
#OTHER WIDGETS AND CODE DEFINED HERE
self.server = None
#SIGNALS
self.clearLogButton.clicked.connect(self.serverLog.clear)
self.stopButton.clicked.connect(self.connectServer)
self.startButton.clicked.connect(self.connectServer)
def connectServer(self):
if (self.server is None):
host = str(self.ipEdit.text())
port = int(self.portEdit.text())
try:
self.server = server.MainServer((host, port), server.MyHTTPHandler)
self.server.setup(self)
self.printLog( "Hooray ! Server connected at {}:{}".format(host, port) )
# Start a thread with the server -- that thread will then start one more thread for each request
MainServer_thread = threading.Thread(target=self.server.serve_forever)
MainServer_thread.daemon = True
self.server.trigger.connect(QtCore.QObject(self.printLog))
MainServer_thread.start()
self.server.trigger.connect(self.printLog)
except errno.EADDRINUSE:
self.printLog("#ERROR: Address already in use. Try a different port.")
except errno.EADDRNOTAVAIL:
self.printLog("#ERROR: Address not available.")
def printLog(self, string):
self.serverLog.append(_fromUtf8(string))
そしてサーバークラスでは:
class MainServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
trigger = QtCore.pyqtSignal(str)
def printLog(self, message):
print message
self.trigger.emit(message)
しかし、アプリを実行すると、次のエラー メッセージが表示されます。
TypeError: pyqtSignal must be bound to a QObject, not 'instance'
別のスレッド (およびクラス) から UI を更新する他の (簡単な) 方法がある場合、またはこのエラーを修正する方法を知っている場合は、お知らせください。