Kalkulator z GUI

0

Witam

Tak jak w temacie, musze napisać kalkulator w gui (dość prosty ale obsługujący funkcje typu sinus, sqrt i nawiasy). Myślałem, żeby użyć w tym celu modułu parsera wygenerowanego przez bisona i flexa. Problem w tym, że taki moduł kompiluje się do oddzielnego programu i działa jako osobny proces. Wiem, że w Qt jest klasa QProcess i można by jej użyć w celu komunikacji z parserem. Niestety muszę to napisać w dwóch bibliotekach GUI i pomyślałem o GTKmm, niestety tam nie ma odpowiednika QProcess. Znalazłem w internecie informacje, że istnieje funkcja popen(), która jakoś tworzy proces potomny i pobiera dane z jego wyjścia. Nie wiem tylko, czy czegoś takiego mógłbym użyć w plikacji GUI (tzn. czy np. mi się okno jakoś nie zablokuje czy coś w tym stylu...). Proszę doświadczonych forumowiczów o poradę.

1

Możesz spokojnie popen użyć. Ja używałem popen w mojej aplikacji w Pythonie + PyQt ( http://commondatastorage.googleapis.com/jason_gd/CSP_1D.png ). Używała ona w popenie PHP do obliczeń w algorytmie genetycznym. Musisz tylko odpalić popen w oddzielnym wątku, wtedy nie blokuje Ci głównego wątku aplikacji. Napisz w wx i Qt. Jeśli chodzi o parsowania sin, sqrt, nawiasów itp., to ja bym to zrobił bardzo szybko, popen+interpreter jakiegoś języka skryptowego (jeśli możesz zrobić takie oszukaństwo) :D Python władowany do jednego pliku exe to jakieś 3MB, PHP mam w wersji zajmującej 5.8MB.

edit

Dobra, rozwiązanie z interpreterami, popenami itp. to zło :D W świecie OpenSource istnieje jeszcze lepsze rozwiązanie: http://www.gnu.org/software/libmatheval/ - robisz w C++, więc możesz tego sobie użyć.

ps. na przyszłość tagi jakoś rozdzielaj.

0

No właśnie, z tymi wątkami jest problem, bo za bardzo ich nie umiem. Jak wywołać popen w oddzielnym wątku i zwrócić wynik do wątku GUI ? Użyć pthreads czy innej biblioteki ? Najchętniej napisałbym to w C++... I dlaczego wx a nie Gtkmm ?

A co do tej biblioteki libmatheval, to rzeczywiście mógłby być to dobry pomysł, tylko z tego co widzę, to ona oblicza wartość funkcji w punkcie, a ja potrzebuję obliczyć wartość wyrażenia np. sin( exp(2.21) + 2.5^3 ). No i druga sprawa - nie ma jej na serwerze uczelnianym. Daloby się ją jakoś ewentualnie dolinkować statycznie ?

1

Qt ma własne wątki QThread, druga biblioteka GUI to mogłoby być wx, on też ma swoje wątki, wxThread, ale skoro jesteś spętany tym co masz na serwerze, to nie wiem, czy wx'y tam są. A dlatego wx, że hmmm, zawsze dla mnie to był po prostu pierwszy wybór zaraz po Qt ;)
Z poziomu wątku nie można bezpośrednio czegoś wpisać do GUI, Qt wyrzuca wtedy błąd, ale możesz sobie przepisywać dane przez jakąś zmienną pośredniczącą ;)

libmatheval ma otwarte źródło, więc nawet jak nie zlinkujesz tego statycznie, to możesz dodać cały kod biblioteki do projektu i też będzie działać - może z drobnymi zmianami w ścieżkach do plików nagłówkowych itp. Robiłem tak kiedyś z jedną biblioteką do GUI współpracującą z SDL+OpenGL. A wzór możesz podawać bez zmiennej x i też będzie dobrze :)

Masz tu kod w libmatheval bez "f(x)" dla Twoich przykładowych danych (przerobiłem kod z tutoriala...):

     #include <stdio.h>
     #include <stdlib.h>
     #include <string.h>
     #include <assert.h>
     #include <matheval.h>
     
     /* Size of input buffer.  */
     #define BUFFER_SIZE 256
     
     /* Program is demonstrating use of GNU libmatheval library of procedures
        for evaluating mathematical functions.  */
     int
     main (int argc, char **argv)
     {
       char buffer[BUFFER_SIZE];	/* Input buffer.  */
       int length;			/* Length of above buffer. */
       void *f;		/* Evaluators for function and function derivative.  */
       
       strcpy(buffer,"sin( exp(2.21) + 2.5^3 )");
       
       length = strlen (buffer);
       if (length > 0 && buffer[length - 1] == '\n')
         buffer[length - 1] = '\0';
     
       /* Create evaluator for function.  */
       f = evaluator_create (buffer);
       assert (f);
     
       /* Calculate and print values of function.  */
       printf ("%g\n",evaluator_evaluate_x (f, 0.0));
     
       /* Destroy evaluators.  */
       evaluator_destroy (f);
     
       exit (EXIT_SUCCESS);
     }

Daje wynik: -0.38206
Kąt w sinusie pobiera w radianach, nie doszukałem się jak wygląda tam funkcja rad2deg.
Python też tak standardowo interpretuje argumenty funkcji trygonometrycznych, daje mi wynik: -0.3820604233284872

0

Czyli jednak się da obliczać zwykłe wyrażenia. Ok, jutro nad tym posiedzę. Jak na razie dzięki wielkie.

0

Jeśli chodzi o parser, to ja używałem http://boost-spirit.com/home/ – niestety początki są trudne. Ale sam parser był szybszy od Bisona.

1 użytkowników online, w tym zalogowanych: 0, gości: 1