Russian Qt Forum
Ноябрь 23, 2024, 00:45 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Взаимодействие между интерфейсом и консольной программой  (Прочитано 6717 раз)
GrimmXXX
Гость
« : Октябрь 23, 2014, 16:56 »

Здравствуйте форумчане.
Я новичок в программировании(эх, как будто это кого-то оправдывало Улыбающийся), поэтому вопросы будут скорее глупыми чем серьезными и занятными.
Так получилось что начал я свое знакомство с программирования на Common Lisp. Пользуюсь SBCL+Slime. Пишу небольшие программы для сложных математических расчетов.
Но дело не в этом. Программы все консольные, а написать интерфейс на sbcl оказалось для меня нетривиальной задачей. Коллеги на работе посоветовали написать интерфейс на C++ и прикрутить его к моей программе. Опыта программирования на C++ у меня нет. В простых примерах я разобрался, а вот дальше...

Вроде задача-то простая: Создать окно, создать на нем несколько кнопок, повесить на каждую кнопку свой текст (код на sbcl) который при нажатии просто отправляется в консоль.
Таким образом при запуске программы должен запускаться процесс c SBCL в консоли, а при нажатии одной из кнопок, текст(код на sbcl) отправляется в консоль и выполняется, причем ответ будет в графическом виде в gnuplot и по идее ответ из консоли принимать не обязательно, хотя было бы неплохо чтобы можно было читать ответ и отсылать его в интерфейс.

Все что я смог сделать это запускать SBCL с кнопки.
Гугление не особо помогло.
Можете накидать пример кода, чтобы при нажатии определенная команда отправлялась в консоль. По небольшому примерчику я думаю разберусь.  Заранее спасибо.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #1 : Октябрь 23, 2014, 17:13 »

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

http://www.prog.org.ru/index.php?topic=24084.msg170886#msg170886

Это синхронный обмен, так же можно сделать асинхронный через сигналы слоты.
Записан
GrimmXXX
Гость
« Ответ #2 : Октябрь 23, 2014, 17:46 »

Спасибо за пример.
Код:
#include <QCoreApplication>
#include <QProcess>
#include <QDebug>

int main( int argc, char *argv[] )
{
        QCoreApplication app( argc, argv );

        QProcess process;
        process.start("/bin/bash");
        process.waitForStarted();

        process.write("sbcl\n");
        process.waitForReadyRead();
        qDebug() << process.readAll();

        process.write("(+ 3 2)\n");
        process.waitForReadyRead();
        qDebug() << process.readAll();

        process.write("exit\n");
        process.waitForFinished();

        return 0;
}
Похоже я не совсем понял что я написал Улыбающийся
Но вот переделал немного пример, но в окне QDebug выводится "* " а должен выводиться ответ 5.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #3 : Октябрь 23, 2014, 17:48 »

Спасибо за пример.
Запускайте вместо bash сам интерпретатор.
Записан
GrimmXXX
Гость
« Ответ #4 : Октябрь 23, 2014, 17:56 »

Спасибо за пример.
Запускайте вместо bash сам интерпретатор.

Код:
#include <QCoreApplication>
#include <QProcess>
#include <QDebug>

int main( int argc, char *argv[] )
{
        QCoreApplication app( argc, argv );

        QProcess process;
        process.start("sbcl\n");
        process.waitForStarted();

        process.write("(+ 3 2)\n");
        process.waitForReadyRead();
        qDebug() << process.readAll();

        process.write("exit\n");
        process.waitForFinished();

        return 0;
}

Вот код. Извините, чувствую себя балбесом который не понимает простых вещей. В окне QDebug выводится просто ". Может попробовать выводить не в QDebug а в LXTerminal? Заранее извините за назойливость.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #5 : Октябрь 23, 2014, 18:23 »

Код
C++ (Qt)
#include <QCoreApplication>
#include <QProcess>
#include <QDebug>
 
int main( int argc, char *argv[] )
{
QCoreApplication app( argc, argv );
 
QProcess process;
process.start( "sbcl --script test.cl" );
process.waitForFinished();
qDebug() << process.readAll();
 
return 0;
}
 

test.cl
Код
Lisp
(PRINT( + 2 3 ))
 
Записан
GrimmXXX
Гость
« Ответ #6 : Октябрь 23, 2014, 18:33 »

Спасибо, что уделяете время, но в окне все равно пустые кавычки.
Код:
Starting /home/grimmxxx/build-Primer-Desktop-Debug/Primer...
""
/home/grimmxxx/build-Primer-Desktop-Debug/Primer exited with code 0
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #7 : Октябрь 23, 2014, 18:38 »

Спасибо, что уделяете время, но в окне все равно пустые кавычки.
Вам нужно правильно установить рабочий каталог, что бы лисп мог находить файл со скриптом. Или указывайте полный путь до этого файла в параметрах.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #8 : Октябрь 23, 2014, 18:52 »

На самом деле использовать паймы это толльо один из возможных вариантов взаимодействия.
Программа на лиспе может писать результаты в файл или общую память, передавать через локальные или сетевые сокеты, работать через какой нибудь DBus. В общем вариантов много и они зависят от объемов этих результатов, необходимой интерактивности вычислений и личных предпочтений. Улыбающийся
Записан
GrimmXXX
Гость
« Ответ #9 : Октябрь 23, 2014, 19:16 »

На самом деле использовать паймы это толльо один из возможных вариантов взаимодействия.
Программа на лиспе может писать результаты в файл или общую память, передавать через локальные или сетевые сокеты, работать через какой нибудь DBus. В общем вариантов много и они зависят от объемов этих результатов, необходимой интерактивности вычислений и личных предпочтений. Улыбающийся

Может вы мне посоветуете тогда какой подход будет для меня оптимальным и ткнете в какую-то литературу?
Программа на Лиспе проводит полный электродинамический анализ различных структур(вибраторы, антенны и т.д.), строит графики токов, 2D и 3D диаграммы направленности в gnuplotе.
В идеале должно быть так:
1)Пользователь запускает программу, одновременно запускается sbcl в фоне.
2)Выводится окно которое содержит надписи, пустые поля для ввода и несколько кнопок.
3)Пользователь вводит в пустые поля нужные данные(параметры структуры).
4)После ввода нажимается кнопка и введенные данные отправляются в sbcl(в определенной форме записи конечно)
5)В конце пользователь нажимает кнопку что-то вроде "Расcчитать" и после расчета выходит окно gnuplot с необходимым ему графиком.

Это все очень грубо и упрощенно,но суть думаю ясна.
« Последнее редактирование: Октябрь 23, 2014, 20:07 от GrimmXXX » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #10 : Октябрь 23, 2014, 19:39 »

Самым лучшим для этого встроить интерпретатор лиспа в программу на C++.
Посмотрите на этот проект: http://ecls.sourceforge.net/
Или попробуйте найти аналоги.
Записан
GrimmXXX
Гость
« Ответ #11 : Октябрь 29, 2014, 12:07 »

Если кому интересно, добился того чего хотел Подмигивающий
Программа тестовая, но вполне рабочая.
Код:
[b]myprocess.cpp[/b]

#include "myprocess.h"

myProcess::myProcess(QWidget *parent) : QDialog(parent)
{
    sb.setText("Start SBCL");
    ib.setText("Input Command");
    lb.setText("(+ 3 2)");
    QVBoxLayout *vl=new QVBoxLayout;
    vl->addWidget(&sb);
    vl->addWidget(&te);
    vl->addWidget(&le);
    vl->addWidget(&ib);
    vl->addWidget(&lb);
    setLayout(vl);

    connect(&sb,SIGNAL(clicked()),this,SLOT(startProcess()));
    connect(&ib,SIGNAL(clicked()),this,SLOT(doInput()));
    connect(&lb,SIGNAL(clicked()),this,SLOT(mathstart()));
    connect(&myProc,SIGNAL(readyReadStandardOutput()),this,SLOT(showOutput()));
    connect(&myProc,SIGNAL(readyReadStandardError()),this,SLOT(showOutput()));
}

void myProcess::startProcess()
{
    QString prog="sbcl";
    myProc.start(prog);
    if(myProc.waitForStarted())
        te.append(QString("Program <b>%1</b> started").arg(prog));
    else
        te.append(QString("Can't start program <b>%1</b>").arg(prog));
}

void myProcess::doInput()
{
    QString s=le.text()+"\n";
    if(myProc.write(s.toAscii())!=-1) le.clear();
}

void myProcess::showOutput()
{
    te.append(QString::fromLocal8Bit(myProc.readAllStandardOutput()));
    te.append(QString::fromLocal8Bit(myProc.readAllStandardError()));
}
void myProcess::mathstart()
{
    QString h="(+ 3 2)\n";
    myProc.write(h.toAscii());
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    myProcess p;
    p.show();
    return a.exec();
}

Код:
[b]myprocess.h[/b]

#include <QtGui>

class myProcess : public QDialog
{
    Q_OBJECT

public:
    myProcess(QWidget *parent=0);
private slots:
    void startProcess();
    void showOutput();
    void doInput();
    void mathstart();
private:
    QProcess myProc;
    QTextEdit te;
    QLineEdit le;
    QPushButton sb,ib,lb;

};

При нажатии кнопки "StartSBCL" запускается собственно сам SBCL(можно запустить любую другую программу). Если ввести какую-то команду в Текстовое поле и нажать "Input Command", то эта команда выполнится в SBCl и ответ выведется в другое текстовое поле. Кнопка "(+ 3 2)" чисто для проверки, чтобы можно было вешать какой-то код заранее прописанный в программе. Теперь хочу ещё добавить пару текстовых полей для переменных, чтобы вводить не всю команду на lispe, а только значения переменных. Спасибо ещё раз за помощь.
« Последнее редактирование: Октябрь 29, 2014, 12:16 от GrimmXXX » Записан
GrimmXXX
Гость
« Ответ #12 : Ноябрь 02, 2014, 09:51 »

Возник ещё один вопрос, но новую тему решил не создавать.
Какой сигнал отвечает за запуск программы?  Хотелось бы запускать процесс описанный выше, сразу при запуске программы, а не при нажатии кнопки "Start SBCL".
Заранее, спасибо за ответ.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #13 : Ноябрь 02, 2014, 09:54 »

QProcess посылает сигнал started, когда дочерний процесс запустился.
Записан
Alexu007
Гость
« Ответ #14 : Ноябрь 02, 2014, 22:32 »

Если программы не сложные (хоть и для сложных матем. вычислений) - не проще скопировать код вычислений в оконное приложение?  Нафига консоли и лишняя головная боль? Само оконное приложение с кнопками и вводом-выводом пишется в Qt за 5 минут.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.079 секунд. Запросов: 22.