обновление в режиме реального времени Qt TextView - PullRequest
4 голосов
/ 10 августа 2010

У меня есть приложение Qt со встроенным скриптом / jit.Теперь я хотел бы получить выходные данные из скрипта в QTextEdit (более конкретный QPlainTextEdit).Для этого вызываются обратные вызовы.Проблема, с которой я сталкиваюсь, заключается в том, что, что бы я ни пытался, вывод в TextEdit либо задерживается, пока скрипт не завершится, либо застревает через 2-3 секунды (и затем задерживается, пока скрипт не завершится).Я пытался использовать сигналы и слоты для обновления, а также прямые вызовы функций - ни сработало.Кроме того, перерисовка / обновление TextEdit и родительской формы, а также даже QCoreApplication :: flush () не показали никакого эффекта / никакого эффекта.Похоже, я делаю что-то в корне неправильно.Любые идеи или примеры, как получить обновления в режиме реального времени?

Кстати, процедуры обновления вызываются - отладочный вывод на стандартный вывод доступен в режиме реального времени.

Ответы [ 2 ]

1 голос
/ 12 августа 2010

Пожалуйста, позвольте мне ответить на вопрос самостоятельно (по частям). Прежде всего, нужно понять, что сам Qt построен в основном на основе собственной концепции сигналов и слотов. Следовательно, нельзя ожидать обновления QTextView в режиме реального времени, поскольку добавление в него текста (может быть с помощью текстового курсора или простого добавления) просто вызывает сигнал. Поэтому, что бы вы ни делали, когда у вас есть только один поток, все, что вы делаете, это запускаете сигналы для обновления ваших виджетов. Соответствующие слоты будут обрабатываться с гораздо более низким приоритетом и, следовательно, после завершения рабочей процедуры блокировки. Все это можно облегчить, вызвав QCoreApplication :: processEvents (), как указано в комментариях Идана К. Это обеспечивает последовательную обработку всех необработанных событий и их последующий возврат. Используя эту функцию, QTextEdit можно использовать как выходную консоль в режиме реального времени. Однако, как указали Идан и Грег, лучшее решение использует отдельный рабочий поток, посылающий сигналы в поток GUI. Поскольку это отдельные потоки, графический интерфейс может обрабатывать соответствующие слоты, пока рабочий продолжает работать. Таким образом, теоретически вывод может быть немного запоздалым. к вышеупомянутому решению, но все приложение останется отзывчивым.

Также хочу добавить, что мои проблемы с использованием QThread вместе с mono были решены путем создания глобального домена приложения вне thethread и использования mono_thread_attach (), как предложено здесь . Хорошо работает как на Mac OS X, так и на Windows 7.

1 голос
/ 10 августа 2010

Просто для того, чтобы набросать решение, используя потоки, которые я много раз использовал для ведения журналов и которые работают как нужно:

Определите свой класс потоков:

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).Это работает без каких-либо задержек или других проблем.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...