“实时”更新Qt TextView

时间:2010-08-10 07:39:03

标签: c++ qt mono qt4

我有一个带有嵌入式脚本/ jit的Qt应用程序。现在我想在QTextEdit(更具体的QPlainTextEdit)上接收脚本的输出。为此目的,正在发布回调。我面临的问题是,无论我尝试输出到TextEdit,要么延迟到脚本完成,要么在2-3秒后卡住(并且延迟到脚本完成)。 我试图使用信号和插槽进行更新,但也直接调用函数 - 两者都没有用。重新绘制/更新TextEdit和父窗体以及甚至QCoreApplication :: flush()确实显示很少/没有效果。好像我在做一些根本错误的事情。任何想法或例子如何实现“实时”更新?

顺便说一下,正在调用更新例程 - 可以实时调试输出到stdout。

2 个答案:

答案 0 :(得分:1)

仅使用线程绘制一个溶质,我已经多次使用它来进行日志记录,并且可以按照需要运行:

定义你的线程类:

class MyThread : public QThread
{
  Q_OBJECT
public:
  MyThread(QObject *parent=0) : QThread(parent) {}
signals:
  void signalLogMessage(const QString &logMessage);

...
};

每当您希望在主线程中显示日志消息时,只需使用

即可

emit signalLogMessage("Foo!");

在主线程中:

MyThread *thread = new MyThread(this);
connect(thread, SIGNAL(signalLogMessage(const QString&)), 
        this, SLOT(logMessageFromThread(const QString&)));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
...
thread->start();

其中logMessageFromThread执行myPlainTextEdit->appendPlainText(message)之类的操作。 这没有任何延迟或其他问题。

我希望有所帮助。

答案 1 :(得分:1)

请允许我自己回答这个问题(部分内容)。 首先,我必须明白Qt本身是围绕自己的信号和插槽概念构建的。因此,人们不能期望QTextView的“实时”更新,因为向其添加文本(可能是通过文本光标或简单附加)只是触发信号。因此,无论您何时只有一个线程,您所做的就是触发更新小部件的信号。相应的插槽将以低得多的优先级进行处理,因此在阻塞工作程序完成之后。所有这些都可以通过调用Idan K的注释中指出的QCoreApplication :: processEvents()来缓解。这将强制执行所有未处理事件的顺序处理并在之后返回。使用此函数,QTextEdit可用作“实时”输出控制台。 然而,正如Idan和Greg所指出的,最佳解决方案使用单独的工作线程,向GUI线程发出信号。由于这些是单独的线程,GUI可以在工作程序继续运行时处理相应的槽。所以理论上的输出可能会有点延迟。对于上述解决方案,但整个应用程序将保持响应。

另外,我想补充一点,我的问题是使用QThread和mono一起解决,通过在线程外创建全局app-domain并使用mono_thread_attach()建议here。它适用于Mac OS X和Windows 7。