Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > Работа с консолью в Qt


Автор: Isaev 19.7.2012, 15:49
Доброго всем дня!

Проблема в следующем: Имеется консольное приложение, которое запускается в виде терминала и принимает свой ограниченный набор команд
Нужно сделать GUI надстройку, т.е. по нажатию кнопки запустить, считать данные ответа из консоли и вывести на форму

Если я правильно понял, то класса http://doc.trolltech.com/4.4/qprocess.html#setProcessChannelMode  должно хватить для выполнения данной задачи

и так ближе к коду... вот что вышло:
Код

 QProcess term;
    term.setProcessChannelMode(QProcess::MergedChannels);
 
    term.start("gnome-terminal");
    if (!term.waitForStarted())  {
      ui->listWidget_bs->addItem("Terminal Start Fehler");
      exit;
    }
    // до этого момента всё ок
    term.waitForReadyRead(); 
    QByteArray res;
    
    term.write("echo hello"); // а вот это в консоль уже не пишется!
    term.write("\n");
 
    term.waitForReadyRead();
    res = term.readLine(); // И, соответственно, тут ничего не читается!


программа запускает консоль, но не выводится ничего, просто пустая консоль запускается
приложение где-то подвисает, возможно на term.waitForReadyRead();
при этом консоль пустая, но реагирует на команды с клавиатуры
через пол минуты убивается автоматом с сообщением
QProcess: Destroyed while process is still running. (в окошке ошибок снизу)
только потом доходит до команды вывода результата, и он пустой, даже если что-то вводишь сам

Собираю под Ubuntu тот же пример собирали под Windows и там всё работает
Как бороться с данной проблемой?

Автор: borisbn 19.7.2012, 15:55
Цитата(Isaev @  19.7.2012,  15:49 Найти цитируемый пост)
term.waitForReadyRead();

Цитата(Isaev @  19.7.2012,  15:49 Найти цитируемый пост)
term.write("echo hello");

ничего в глаза не бросается ?
убери этот waitForReady. он там не нужен.
если интересует, я могу скинуть обёртку над консольным приложением. как-то делал...

Автор: Isaev 19.7.2012, 16:16
Цитата(borisbn @  19.7.2012,  15:55 Найти цитируемый пост)
ничего в глаза не бросается ?убери этот waitForReady. он там не нужен.

пошел грузить убунту и пробовать

Цитата(borisbn @  19.7.2012,  15:55 Найти цитируемый пост)
если интересует, я могу скинуть обёртку над консольным приложением. как-то делал...

интересует очень... Отпало бы сразу множество вопросов. Буду очень признателен.

думал вообще придётся велосипед изобретать, а тут вроде более-менее работа с терминалом есть.

Автор: borisbn 19.7.2012, 17:17
Лови: http://yadi.sk/d/4YOWR-0Z02X9

Автор: Isaev 31.7.2012, 16:46
borisbn пример правильного использования можно?

Проблемка в том, что при запуске программки она ищёт устройства вокруг в бесконечном цикле, пока не получает команду стоп, параллельно отображая найдённые в консоли...

получается я могу послать команду стоп, потом считать ответ из консоли
а можно как-то реагировать на то, что в консоль добавилась новая строка и сразу её получать?
т.е. чтобы в GUI процесс поиска был виден, а не жать постоянно стоп/старт не зная найдено там уже что-то или нет

ну и глупый вопрос до кучи:
как сделать чтобы консоль запускалась а root mode?

Автор: borisbn 3.8.2012, 14:58
Цитата(Isaev @  31.7.2012,  16:46 Найти цитируемый пост)
 пример правильного использования можно?

Код

// твой h-файл
#include "WindowsWrapper.h"

class YourClass : public QWidget
{
Q_OBJECT
public:
    YourClass();
private:
    WindowsWrapper m_consoleWrapper;
private slots:
    void onReadyRead( QString line );
};

// твой cpp-файл
YourClass::YourClass()
    : m_consoleWrapper( "/path/to/console/prog/", "prog_name" )
{
    connect( &m_consoleWrapper, SIGNAL( lineReaded( QString ) ), SLOT( onReadyRead( QString ) ) );
    m_consoleWrapper.start();
}

void YourClass::onReadyRead( QString line )
{
    // делаешь со строкой чо хошь :)
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)