Python QObject(QPlainTextEdit)和;多线程问题

Python QObject(QPlainTextEdit)和;多线程问题,python,multithreading,qt4,pyqt4,asyncore,Python,Multithreading,Qt4,Pyqt4,Asyncore,我目前正在尝试学习使用Python asyncore和pyqt4进行联网 我编写了一个小型服务器,它基本上监听某个端口,并将收到的所有消息重新发送给发送者 由于qtsQApplication.exec\uuz()和asyncore.loop()都是永不返回的函数,我无法在一个线程中启动它们,因此我在一个单独的守护进程线程中启动了asyncore.loop() 每当我的服务器类(派生自asyncore.dispatcher)建立或断开连接,或发送/接收消息时,它都会调用我的窗口类(派生自QtGui

我目前正在尝试学习使用Python asyncore和pyqt4进行联网

我编写了一个小型服务器,它基本上监听某个端口,并将收到的所有消息重新发送给发送者

由于qts
QApplication.exec\uuz()
asyncore.loop()
都是永不返回的函数,我无法在一个线程中启动它们,因此我在一个单独的守护进程线程中启动了
asyncore.loop()

每当我的服务器类(派生自
asyncore.dispatcher
)建立或断开连接,或发送/接收消息时,它都会调用我的窗口类(派生自
QtGui.QMainWindow
)的方法,该窗口类在
QPlainTextEdit
中显示信息

但是文本不可见,除非用鼠标标记文本

Python控制台显示以下错误消息:

QObject::connect: Cannot queue arguments of type 'QTextBlock'
(Make sure 'QTextBlock' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QTextCursor'
(Make sure 'QTextCursor' is registered using qRegisterMetaType().)
我在一些论坛上读到,这可能是由从另一个线程调用qt函数引起的,使用signals&slot而不是普通的函数调用可以解决这个问题,但是我也尝试了signals,我仍然得到这个错误

那么,(如果这真的是我的问题的原因)从另一个线程调用qt对象的方法的正确方法是什么

编辑更多信息: asyncore.loop()调用位于子线程中,它不是真正的阻塞,而是只有在asyncore.loop()的运行时,我的服务器类(asyncore.dispatcher)才能进行联网。 因此,在asyncore.loop()的运行时,我的服务器类的方法由asyncore.loop()调用(=子线程),在这些方法中 试图向主线程中运行的窗口类发出信号

编辑:看起来我现在已经开始工作了,我的代码中有一些错误,现在信号一切正常


编辑:小示例:(死链接)

您似乎试图从主线程以外的线程访问QtGui类。与其他一些GUI工具包(如JavaSwing)一样,这是不允许的。从网页:

虽然QObject是可重入的,但GUI 类,尤其是QWidget及其所有 子类是不可重入的。他们 只能从主线程使用

解决方案是使用信号和插槽在主线程(GUI对象所在的位置)和辅助线程之间进行通信。基本上,您在一个线程中发出信号,这些信号通过另一个线程传递给QObject。我上面链接的页面对此进行了很好的讨论。事实上,整个章节都读得很好


您可能遇到的一个潜在问题是,通常情况下,要获得跨线程工作的完整信号和插槽支持,您需要在子线程中使用
QThread::exec()
(或PyQt等价物)启动事件循环,以便将信号传递到位于其中的QObject中的插槽。在您的情况下,听起来像是在对
asyncore.loop()
进行阻塞调用,这将阻止您执行此操作。但是,如果您只需要在一个方向上发出信号(从子线程到主线程中的小部件),我认为您不会有问题。

错误消息确实表明他试图进行信号/插槽连接。但是,QTextBlock数据类型不是注册的QMetaType,因此不能由线程之间的连接承载。。。但是我如何使用QThreads来解决我的问题呢???,因为QThreads
exec()\uu
方法又是一个阻塞方法,所以我不能像我的服务器类那样在同一个线程中运行它
@e8johan:当我没有使用信号时,我收到了相同的错误消息。你能发布一个解释或工作解决方案的片段吗?它肯定会在将来帮助其他有同样问题的人