QObject(QPlainTextEdit)&多线程问题 [英] QObject (QPlainTextEdit) & Multithreading issues

查看:379
本文介绍了QObject(QPlainTextEdit)&多线程问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Im currently trying to learn Networking with Python asyncore and pyqt4.

我编码了一个小型服务器,该服务器基本上在某个端口上侦听,然后将接收到的所有消息重新发送给发件人.

I coded a small server, which basically listens on some port, and resends all messages it recieves to the sender.

由于qts QApplication.exec_()asyncore.loop()都是永不返回的函数,因此我无法在一个线程中同时启动它们,因此我在单独的守护程序线程中盯着asyncore.loop().

Since both qts QApplication.exec_() and asyncore.loop() are functions which never return i could not start them both in one thread, so i stared asyncore.loop() in a seperate daemon thread.

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

Whenever my server class (derived from asyncore.dispatcher) establishes or drops a connection, or sends/recieves a message, it calls methods of my window class (derived from QtGui.QMainWindow), which displays the information in a QPlainTextEdit.

但是除非您用鼠标标记文本,否则文本是不可见的.

But the text is not visible, unless you mark the text with the mouse.

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

Python console displays following error msg:

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-functions以及使用signal&插槽而不是简单的函数调用可能会解决此问题,但是我也尝试过信号,但仍然会收到此错误.

I read on some forum, that this may be caused by calling qt-functions from another Thread, and that using signals & slots instead of plain function calling may fix the issue, but i have tried signals aswell, and i still get this error.

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

So, (if that is really the cause of my problems) whats the correct way to call methods of an qt object from another thread ?

编辑更多信息: asyncore.loop()调用位于子线程中,它实际上并没有阻塞,但仅在asyncore.loop()运行时,我的Server类(asyncore.dispatcher)才能进行联网. 因此,在asyncore.loop()的运行期间,我的Server类的方法被asyncore.loop()(=子线程)调用,并且在这些 试图向运行在主线程中的窗口类发出信号

EDIT More Info: the asyncore.loop() call is located in the child thread, well its not really blocking, but only during the runtime of asyncore.loop() my Server class (asyncore.dispatcher) can do networking. So, during the runtime of asyncore.loop() the methods of my Server class ARE called by asyncore.loop() (=child thread), and in these i tried to emit signals to the window class running in the main thread

编辑:好像我现在可以正常工作了,我的代码中有一些错误,现在一切都按信号正常工作了.

Seems like i got it working now, i had some errors in my code, everything works as intended with signals now.

小例子: http://paste2.org/p /635612 (无效链接)

small example: http://paste2.org/p/635612 (dead link)

推荐答案

似乎您正在尝试从主线程以外的其他线程访问QtGui类.就像其他一些GUI工具包(例如Java Swing)一样,这是不允许的.从线程和QObjects 网页:

It appears you're trying to access QtGui classes from a thread other than the main thread. Like in some other GUI toolkits (e.g. Java Swing), that's not allowed. From the Threads and QObjects web page:

尽管QObject是可重入的,但GUI 类,尤其是QWidget及其所有 子类,不可重入.他们 只能在主线程中使用.

Although QObject is reentrant, the GUI classes, notably QWidget and all its subclasses, are not reentrant. They can only be used from the main thread.

一种解决方案是使用信号和插槽在主线程(GUI对象所在的位置)和辅助线程之间进行通信.基本上,您在一个线程中发出信号,该信号通过另一线程传递给QObject.我上面链接的页面对此进行了很好的讨论.实际上, Qt中的线程支持的整个部分都是不错的读物.

A solution is to use signals and slots for communication between the main thread (where the GUI objects live) and your secondary thread(s). Basically, you emit signals in one thread that get delivered to the QObjects via the other thread. The page I linked to above has a good discussion of this. Actually, the whole section on Thread Support in Qt is a good read.

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

One potential issue you could run into is that, normally, to get full signals and slots support working across threads, you need to start an event loop in the child thread using QThread::exec() (or the PyQt equivalent) so that signals can be delivered to slots in the QObjects that live there. In your case, it sounds like you're making a blocking call to asyncore.loop(), which will prevent you from doing this. But, if you only need to emit signals in one direction (from the child thread to widgets in the main thread), I don't think you'll have a problem.

这篇关于QObject(QPlainTextEdit)&多线程问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆