Название: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: Gordey1978 от Июль 01, 2010, 20:41 Всем привет.
Помогите пожалуйста наладить перехват stdout консольного приложения. Использую QT 4.6.3 и Microsoft Visual Studio 2008. Задача: из Qt GUI запустить консольное приложение, перехватить его стандартный поток ввода/вывода и вывести перехваченные данные в элемент QTextEdit. Консольное приложение в цикле валит в поток вывода строки Value: 1 Value: 2 Value: 3 и т.д. #include <iostream> int main(int argc, char* argv[]) { for(int i =0; i != 1000000; ++i) std::cout << "Value: " << i << std::endl; return 0; } В Qt GUI при нажатии на кнопку создается отдельный поток. process = new QProcess; process->setProcessChannelMode(QProcess::MergedChannels); connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(output())); process->start("test_console.exe"); exec(); При создании потока запускаем процесс с консольным приложением. При получении сигнала readyReadStandardOutput() отправляем считанные данные родительскому приложению. void ServerThread::output() { QByteArray bytes = process->readAllStandardOutput(); emit updateOutput(bytes); } В Qt GUI получаем посылку с данными и выводим ее в QTextEdit. void MainWindow::setOutput(const QString &msg) { ui->textEdit->insertPlainText(msg); } Проблема в том, что при перехвате потока ввода/вывода и выводе данных в QTextEdit происходит залипание Qt GUI. То есть я практически ничего не могу сделать с родительским окном. Как можно решить данную проблему? Как избавиться от залипания QT окна? При решении проблемы изменять код консольного приложения нельзя , нужно решить задачу другими способами. Файлы проектов выложил на Скачать test.rar с WebFile.RU (http://webfile.ru/4590573) Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: kuzulis от Июль 01, 2010, 20:52 А вы проверьте, действительно ли QProcess работает в другом потоке?
--- что-то у меня скачался архив в котором только main.cpp Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: Gordey1978 от Июль 01, 2010, 20:55 А вы проверьте, действительно ли QProcess работает в другом потоке? А как проще проверить? Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: BRE от Июль 01, 2010, 20:55 Попробуй:
Код
Код
Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: BRE от Июль 01, 2010, 20:56 А как проще проверить? Посмотреть, что выводит QThread::currentThreadId()Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: kuzulis от Июль 01, 2010, 20:59 Шо ви выкладываете хрень какую-то в аттач? То в *.zip ошибка в архиве, то в *.rar один только main.cpp!?? У меня одного так?
Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: Gordey1978 от Июль 01, 2010, 21:01 Шо ви выкладываете хрень какую-то в аттач? То в *.zip ошибка в архиве, то в *.rar один только main.cpp!?? У меня одного так? Чета архивы портятся при добавлении. Сам обратно заказиваю, а они уже битые. Как выложить то? Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: kuzulis от Июль 01, 2010, 21:01 Ничо не должно бится.. Мож архиватор палёный? :)
Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: Gordey1978 от Июль 01, 2010, 21:03 Попробуй: Код
Код
Не помогло. Залипание не ушло :( Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: Gordey1978 от Июль 01, 2010, 21:04 Ничо не должно бится.. Мож архиватор палёный? :) Да вроде проверенные :-) Сейчас еще попробую... Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: kuzulis от Июль 01, 2010, 21:06 Цитировать Не помогло. Залипание не ушло Грустный Проверьте ID-ы потоков: основного и процессногоНазвание: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: Gordey1978 от Июль 01, 2010, 21:10 А как проще проверить? Посмотреть, что выводит QThread::currentThreadId()На разных. h1 0x00000e40 void * h2 0x00000d60 void * void ServerThread::run() { Qt::HANDLE h2 = QThread::currentThreadId(); } void MainWindow::on_pushButton_clicked() { Qt::HANDLE h1 = QThread::currentThreadId(); } Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: Gordey1978 от Июль 01, 2010, 21:16 Вот еще попытка выложить проекты
Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: kuzulis от Июль 01, 2010, 21:21 Все-равно косяки с архивами.. Как вариант - перед аттачем архивов - уберите расширение *.txt . может поможет.
Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: Gordey1978 от Июль 01, 2010, 21:23 Так как ничего не вышло с архивами дополнительно закачал файлы на webfile.ru
Скачать test.rar с WebFile.RU (http://webfile.ru/4590573) Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: Gordey1978 от Июль 01, 2010, 21:38 Залипание можно убрать если после вывода строки поставить задержку Sleep(1).
Старый вариант: int main(int argc, char* argv[]) { for(int i =0; i != 1000000; ++i) std::cout << "Value: " << i << std::endl; return 0; } Новый вариант: int main(int argc, char* argv[]) { for(int i =0; i != 1000000; ++i) { std::cout << "Value: " << i << std::endl; Sleep(1); } return 0; } Но такой вариант мне не подходит так как консольное приложения я изменить не могу. Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: BRE от Июль 01, 2010, 22:20 Ну тогда дай время главному потоку разгребать все сообщения о пришедших сигналах и на вставку текста:
Код Также можно складывать пришедшие данные в промежуточный буфер и когда соберется определенное количество данных отправлять их одним эмитом. Думаю, стоит обратить внимание на класс QPlainTextEdit, он по-быстрее QTextEdit. Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: Gordey1978 от Июль 02, 2010, 05:56 Ну тогда дай время главному потоку разгребать все сообщения о пришедших сигналах и на вставку текста: Код Также можно складывать пришедшие данные в промежуточный буфер и когда соберется определенное количество данных отправлять их одним эмитом. Думаю, стоит обратить внимание на класс QPlainTextEdit, он по-быстрее QTextEdit. С msleep( 200 ) попробовал... не помогло :-( Все попробовал. Ничего не помогло :-( Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: Гурман от Июль 02, 2010, 14:35 я бы дал идею не просто создать процесс-перехватчик запуском одного QProcess, а запустить второй QThread, в нем запускать QProcess, получать там данные дочернего приложения, и через BlockingQueuedConnection передавать в QTextEdit основной нити - так интерфейс гарантированно блокироваться не будет
у меня в приложении похожим образом работает "консоль" - основные действия выполняются фоновым QThread, из которого через блокирующее соединение вычислитель плюется сообщениями, и эти сообщения валятся в QTextEdit в основном треде только вот QTextEdit при этом все сильно тормозит, он на добавлении строк медлееееееннннннныыыыыыййййй..... :( поэтому при полностью асинхронной работе дочернего приложения вполне возможна потеря части сообщений Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: Gordey1978 от Июль 02, 2010, 15:29 я бы дал идею не просто создать процесс-перехватчик запуском одного QProcess, а запустить второй QThread, в нем запускать QProcess, получать там данные дочернего приложения, и через BlockingQueuedConnection передавать в QTextEdit основной нити - так интерфейс гарантированно блокироваться не будет у меня в приложении похожим образом работает "консоль" - основные действия выполняются фоновым QThread, из которого через блокирующее соединение вычислитель плюется сообщениями, и эти сообщения валятся в QTextEdit в основном треде только вот QTextEdit при этом все сильно тормозит, он на добавлении строк медлееееееннннннныыыыыыййййй..... :( поэтому при полностью асинхронной работе дочернего приложения вполне возможна потеря части сообщений А код отвечающий за перехват и работу через BlockingQueuedConnection не можешь выложить? Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: Гурман от Июль 02, 2010, 19:22 код, отвечающий за перехват - это не мой код, это ваш код...
Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: Gordey1978 от Июль 04, 2010, 08:11 Неужто здесь на форуме нет гуру способных помочь?
Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: niXman от Июль 04, 2010, 21:42 у меня подобная задача работает превосходно.
установи монитор событий на дескрипторе, например, epoll() (http://linux.die.net/man/4/epoll) или select() (http://linux.die.net/man/2/select) Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: niXman от Июль 04, 2010, 22:14 только буферизацию на дескрипторе не забудь отключить ;)
Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: Gordey1978 от Июль 05, 2010, 05:40 у меня подобная задача работает превосходно. установи монитор событий на дескрипторе, например, epoll() (http://linux.die.net/man/4/epoll) или select() (http://linux.die.net/man/2/select) Если это реализовывать на чистых С++ + WinAPI, то и у меня все работает отлично. А вот с QT не очень получается :-( Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: niXman от Июль 05, 2010, 06:19 Цитировать А вот с QT не очень получается :-( а должно? ;)Название: Re: Помогите пожалуйста наладить перехват stdout консольного приложения. Отправлено: Gordey1978 от Июль 05, 2010, 16:47 Цитировать А вот с QT не очень получается :-( а должно? ;)Думаю, что способ есть :-) |