sme*_*lin 8 python multithreading qt4 pyqt4 asyncore
我目前正在尝试使用Python asyncore和pyqt4学习网络.
我编写了一个小型服务器,它基本上监听某个端口,并将收到的所有消息重新发送给发送方.
由于这两种QTS QApplication.exec_()和asyncore.loop()是永不回我不能都在一个线程启动它们的功能,所以我盯着asyncore.loop()在一个单独的守护线程.
每当我的服务器类(派生自asyncore.dispatcher)建立或删除连接,或发送/接收消息时,它都会调用我的窗口类(派生自QtGui.QMainWindow)的方法,这些方法在a中显示信息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().)
Run Code Online (Sandbox Code Playgroud)
我在一些论坛上看到,这可能是由于从另一个线程调用qt-functions引起的,并且使用信号和插槽而不是普通函数调用可能会解决问题,但我也试过了信号,我仍然得到这个错误.
所以,(如果这确实是我的问题的原因)有什么正确的方法从另一个线程调用qt对象的方法?
编辑更多信息: asyncore.loop()调用位于子线程中,它不是真正阻塞,但仅在asyncore.loop()的运行时期间,我的Server类(asyncore.dispatcher)可以进行网络连接.因此,在asyncore.loop()的运行时期间,我的Server类的方法由asyncore.loop()(=子线程)调用,并且在这些我试图向主线程中运行的窗口类发出信号
编辑:好像我现在正在使用它,我的代码中有一些错误,现在所有信号都按预期工作.
编辑:小例子:http://paste2.org/p/635612(死链接)
Rob*_*b H 11
您似乎正在尝试从主线程以外的线程访问QtGui类.与其他一些GUI工具包(例如Java Swing)一样,这是不允许的.从Threads和QObjects网页:
尽管QObject是可重入的,但GUI类(尤其是QWidget及其所有子类)不可重入.它们只能在主线程中使用.
解决方案是使用信号和插槽在主线程(GUI对象所在的位置)和辅助线程之间进行通信.基本上,您在一个线程中发出信号,通过另一个线程传递给QObject.我上面链接的页面对此进行了很好的讨论.实际上,关于Qt中线程支持的整个部分是一个很好的阅读.
您可能遇到的一个潜在问题是,通常,要获得完整信号和插槽支持跨线程工作,您需要使用QThread::exec()(或PyQt等效)在子线程中启动事件循环,以便可以将信号传递到插槽中生活在那里的QObjects.在你的情况下,听起来你正在进行阻止调用asyncore.loop(),这将阻止你这样做.但是,如果你只需要在一个方向发射信号(从子线程到主线程中的小部件),我认为你不会有问题.