Grafikus Felhasználói Felületű (GUI) program készítése a QT Creatorral, illetve a Microsoft Visual Studio-val
A feladat A feladat egy kis számológép elkészítése. A számológép a következőképpen néz majd ki:
Működése pedig a következő: számokat beírhatunk vagy a szám gombokkal, vagy pedig egérrel a számológép GUI gombjaival. A műveleti jeleket is beírhatjuk mindkét módon. Az egyszerűség kedvéért nem egy valódi számológépet csinálunk, csak egy egyszerű modellt. A hiányosságai: zárójelezés nem lehetséges és a műveletek egyenrangúak, vagyis 2 + 3 * 4 nem 14, hanem 20. Azt sem ellenőrizzük le, hogy a beírt sor szintaktikusan helyes-e. A számokat az angolszász országokban szokásos tizedesponttal kell beírni.
Milyen programokat használjunk Amikor a QT-t telepítjük egyúttal a QT Creator –t is telepítjük. Ha ez Windows-ra történik, akkor ennek során kiválaszthatjuk feltelepítjük-e a mingwfordítót, ami a gcc Windows-os változata. Mivel a QT a Microsoft Visual Studio-val is használható erre nem feltétlenül van szükség. Ebben az esetben azonban továbbra is két lehetőség áll fenn: vagy a QT-s kiegészítést használjuk1, amikor is magából a Visual Studioból intézhetünk mindent, vagy a QT Creator-t használjuk a Visual Studio-val, mint fordítóval. Az előbbi a kényelmesebb, mert a Visual Studio program szerkesztője sokkal hatékonyabb, mint a QT Creator-é, továbbá nem kell egyéb telepítésekkel és beállításokkal bajlódjunk.
1
VS 2013 és ez alatt ehhez a qt-vs-addin-1.2.4-opensource.exe VS 2015-re pedig a QT5Package-et kell feltelepíteni.
Linux alatt nincs választási lehetőségünk a QT Creator-t kell használjuk, cserébe viszont nincs szükség újabb telepítésekre.
A QT Creator használata Windows alatt a Microsoft Visual Studio-val Először is fel kell telepítsük a Windows-os WDBG debugger-t a https://developer.microsoft.com/hu-hu/windows/hardware/windows-driver-kit oldalról. Görgessük le az oldalt és válasszuk ki a Hibakereső eszközök beszerzése pontig és töltsük le, majd telepítsük vagy a teljes SDK-t, vagy csak a WinDbg programot! Indítsuk el a QT Creator-t. Az indítási képernyője a következő:
Először ellenőrizzük a beállításainkat a Tools/Options… menüben. Elsősorban A Build & Run oldalt kell megnézzük:
A
jelzi, ha a beállításokkal problémák vannak. Ha a hiányzó konfigurációkat akarjuk
használni, akkor fel kell telepítsük a megfelelő Windows-os debugger-t. Ellenőrizzük a többi beállítást is:
Ha a QT telepítő nem találta meg a QTs programokat, akkor nekünk kell megkeresni és beállítani azokat.
A felhasználói felület elkészítése a QT Designer használatával Windows alatt Microsoft Visual Studio-val Windows alatti QTs fejlesztésekre a QT kiegészítés telepítése után ez a jobb módszer. Ha a kiegészítő telepítése sikeres volt, akkor a Visual Studio menüsorában megjelenik a QT menü, aminek a QT Options almenüjében be kell állítva lennie a rendelkezésre álló QT konfigurációknak:
Válasszuk a New Projekt opciót és a megjelenő ablakban a Qt5 Projects-et ott pedig a Qt Application-t:
Itt nem kell létező könyvtár nevet megadni, az automatikusan létrejön. Válasszuk az OK-t, ami elindítja a Qt projekt varázslót.
A Finish megnyomása után a projekt létre jön2:
A Szamologep.ui-ra duplán kattintva a Qt Designer (designer.exe) nyílik meg, amivel ugyanúgy kell a GUI-t elkészíteni, mint a Qt Creator-ral, de fordítani a Visual Studioból kell, Az alábbiakban a QT Creatort használjuk.
Sajnos nem ilyen jó a helyzet, ha új ablakot kell hozzáadjunk a meglevő projekthez. Akkor kézzel kell sok mindent beállítani. 2
Számológép A GUI elkészítése Kattintsunk a New Project –re! Egy dialógus ablak jelenik meg:
Kattintsunk a Choose…-ra! A megjelenő ablakban adjuk meg mi a projektünk paramétereit. A projekt neve legyen szamologep3, és a könyvtár, amiben létrehozzuk legyen az, ahol a programjainkat akarjuk tárolni. Ez legyen az a könyvtár, ahová a projektjeinket akarjuk tenni, pl. a saját (home) könyvtárunk ban (Windows alatt ez a C:\Users\felhasználó_név/) a QT_projektek alkönyvtár, de persze bárhol máshol lehet, ahol létrehozhatunk könyvtárakat. Ha a könyvtár nem létezik a Browse menüben először létre kell hozzuk.
Nem használok ékezeteket, sőt betűközöket sem a nevekben, egyrészt, mert a mingw-nek ezzel időnként gondjai vannak, másrészt mert azt akarom, hogy a fájlok átvihetőek legyenek Windows-os Visual Studios projektbe. 3
Ezután Next.
Válasszuk ki mindazokat a lehetőségeket, amiket használni akarunk. Majd Next.
Írjuk át ezeket a következőkre: Class name:Szamologep, Header file: szamologep.h, Source file: szamologep.cpp, Form file:szamologep.ui, majd nyomjuk meg a Next gombot!
Ne változtassunk semmit, nyomjuk meg a Finish gombot4! A projektünk most a következőképpen néz ki:
Természetesen aki verziókövetést akar – ez nagyobb projekteknél mindenképpen ajánlatos -, az itt beállíthatja a kedvenc programját, de mi ezt most nem használjuk. 4
Mielőtt tovább lépnénk próbáljuk ki, hogy a program lefordítható-e. Ehhez kattintsunk a ikonra! Ha minden rendben a QT Creator lefordítja, majd elindítja a programot, és a következő ablak jelenik meg:
Zárjuk be ezt az ablakot! A GUI szerkesztéséhez kétszer kattintsunk a Forms alatti szamologep.ui-ra! A GUI szerkesztő ablaka jelenik meg5. Az ablak több panel-t és a szerkesztendő GUI ablakát mutatja:
5
Ez ugyanaz a Designer ablak, mint ami a Visual Studio használata során jelenne meg.
Természetesen a QT Creator-t kinagyíthatjuk teljes képernyőre és az oldalsó paneleket be is zárhatjuk, hogy jobban lássuk a felületet. Az egyes GUI elemeket a bal oldalról választhatjuk ki és a bal egérgombot benyomva tartva húzhatjuk rá a középen levő panel-re. Ekkor ezek megjelennek a jobb oldalon a felső panelen is. Az utoljára kiválasztott elem tulajdonságai jobbra alul láthatóak. Írjuk át a fő ablak (objectName Szamologep)
címfeliratát (windowTitle) Számológép-re: A a Type here -re dupla kattintás után gépeljük be, hogy &Fájl és az alatta megjelenő
almenübe, hogy E&xit:
Ezzel létrehoztunk egy menü action-t. Az Exit-re kattintva a jobb oldalon láthatjuk, hogy az objektumunk neve actionE_xit lesz6 és ez az action megjelenik középen alul az Action Editor-ban is.
Ahhoz azonban, hogy ez az action működjön is szükségünk van még egy függvényre, ami az action használatakor hívódik meg. Ennek megadásához használjuk a Signals & Slots Editort: kattintsunk alul a megfelelő fülre:
A zöld + jelre kattintva adhatunk hozzá új kapcsolatokat. A lépések:
Két kattintás a <sender>-re és egy objektum
listából kiválaszthatjuk az actionE_xit-et:
, majd
hasonlóképpen a többi oszlopot is kitöltjük. A végeredmény7:
Általában egy program legfontosabb funkciói nem csak egérrel de billentyűzetkombinációkkal, ún. gyorsbillentyűkkel (shortcut) is elérhetőek. Egyik kilépésre használt kombináció az Alt+X. Adjunk hozzá ilyet! A jobb oldalon kattintsunk a shortcut-ra. Megnyílik három alpont. Válasszuk ki a shortcut
felirat sorát:
, majd az Alt+X billentyűkombinációt és
kattintsunk valahova máshova, NE nyomjunk be semmilyen más gombot, mert az
megváltoztatná a sort:
6
Az Alt+X szöveget már a QT Creator írja be.
Az aláhúzás az & jel helyett áll. Természetesen bármikor átnevezhetjük átírva az objectName tulajdonságot a jobb oldalon. 7 A close() SLOT egy létező slot-ja a QMainWindow-nak. A QT Creator/QT Designer-rel azonban létrehozhatunk új SIGNAL-okat és SLOT-okat is. Azokat azonban nem elég a szerkesztőben létrehozni, az osztály definícióba is be kell írjuk azokat.
Futtassuk a programot, majd zárjuk be! A GUI szerkesztőben a bal oldalról húzzunk rá egy Line Edit-et az ablakra:
, majd egy Tool Button-t
is adjunk hozzá. Ez lesz a
7-es szám gombja. Írjuk át a nevét toolButton-ról
-re! Válasszuk
ki a jobb oldalon a geometry-t és írjuk át a gomb méreteket 30 pixelre,
, majd lefelé görgetve a jobb alsó panelt válasszuk ki a zöld mezők közül a text –et és írjuk át a három pontot a 7-es számra: . Az egyes különböző színű tömbök az egyes leszármaztatott osztályokat jelölik, legfelül a QObject és QWidget szakaszok, alatta a leszármaztatott osztályok a leszármaztatás sorrendjében.
A Ctrl gombot lenyomva tartva kattintsunk a gombra és nem felengedve az egér gombját húzzuk azt jobbra. Ezzel az eredeti gomb egy másolatát helyeztük el a leendő számológépen. Annak is írjuk át a nevét és szövegét és addig ismételjük ezt, amíg el nem jutunk a végső állapotig:
A szám gombok neve legyen btn0 … btn9, a többié: btnClear, btnSzor, btnPer,btnPlussz, btnMinusz, btnVesszo, btnPm (plussz – mínusz), btnExp és btnEq (egyenlő)
Ahhoz, hogy ez így nézzen ki az ablakot is át kell méretezzük. Ezt a jobb alsó sarkán megfogva tehetjük meg. Futtassuk a programot! Változtassuk meg az ablak méretét és nézzük meg mi történik!
Ez nyilván nem kívánatos, ezért tegyük az ablakot átméretezhetetlenné! Lépjünk ki a programból és a szerkesztőben a jobb oldalon írjuk át az ablak minimum és maximum méretét ugyanarra, mint az aktuális szerkesztett mérete:
Mentsük el az eredményt! Teszteljük le jól működik-e!
A számológép programja Ezután készítjük el a számológépet működtető programot. Válasszuk ki a a bal oldalon a szerkesztés ikont (Edit). Ekkor először a GUI-hoz tartozó XML8 kódot látjuk és a bal oldalán a fájlok listáját. Válasszuk ki a szamologep.h-t (dupla kattintás)! Nézzük meg az automatikusan létrehozott fájlt! Az első két sor az utolsó sorral együtt biztosítja, hogy a fájlt csak egyszer használja a fordító. A privát részben jelenik meg a Ui::Szamologep *ui; sor a QT Creator által generált kódban. A Visual Studio-ban generált sor ezzel szemben: Ui::SzamologepClass ui; lesz. Mindkettő azt jelenti, hogy a színfalak mögött
8
eXtensible Markup Language – egy ember által is olvasható (és elvileg megérthető) kód hierarchiák leírására.
az uic (User Interface Compiler) program a GUI-t leíró XML fájlból egy .h és egy .cpp fájlt generál. Ezzel nekünk nem kell foglalkoznunk. Ennek eredményeként az ui pointer, vagy az ui osztály ad nekünk hozzáférést az egyes widgetekre mutató pointerekhez. Ahhoz, hogy a gombok működjenek mindegyik gomb clicked() SIGNAL-ját ossze kell kötni a fő ablak egy SLOT-jával, ahogy azt tettük a Notepad programban. Ott említettük, hogy van ennek egy egyszerűbb módja is. Most azt fogjuk használni9. Írjuk be a Szamologep osztályba a következő sorokat: private slots: void on_btn0_clicked(); void on_btn1_clicked(); void on_btn2_clicked(); void on_btn3_clicked(); void on_btn4_clicked(); void on_btn5_clicked(); void on_btn6_clicked(); void on_btn7_clicked(); void on_btn8_clicked(); void on_btn9_clicked(); void on_btnClear_clicked(); void on_btnSzor_clicked(); void on_btnPer_clicked(); void on_btnPlussz_clicked(); void on_btnMinusz_clicked(); void on_btnVesszo_clicked(); void on_btnPm_clicked(); void on_btnExp_clicked(); void on_btnEq_clicked();
Vegyük észre a logikát itt: minden SLOT a void on_ -sal kezdődik, ezt követi a SIGNAL-t küldő objektum neve, majd aláhúzás után a SIGNAL neve és - ha van- paramétere. A clicked SIGNAL-nak nincs paramétere ezért üres a (). Nincs szükség a connect függvényre, annak hívását a fordítás során a moc (Meta Object Compiler) programmal a QT elintézi nekünk. A billentyűzettel való bevitelt a lineEdit végzi el. Mindegyik számmal jelzett gomb hozzáragasztja a megfelelő számjegyet a lineEdit- beli szöveg végére. A többi gomb a btnClear, btnPm és btnEq kivételével ugyancsak egy karaktert tagaszt hozzá a lineEdit-hez. Csináljunk erre egy közös függvényt az osztály private részébe a private slots fölé!: void addChar(QChar ch);
A btnClear kitörli a lineEdit szövegét, a btnPm az utolsó beírt szám előjelét változtatja meg, a btnEq pedig kiszámítja a végeredményt. Az egyszerűség érdekében ezekben most semmilyen hibakezelés nem lesz! 9
Ezt megcsinálhatnánk a QT Creator/QT Designer SIgnal/Slot Editor-jával is, de így gyorsabb.
Mindegyik függvény törzsét meg kell írjuk. Mentsük el a változtatásokat, majd válasszuk ki a szamologep.cpp-t és készítsük el ezeket a függvényeket! Először az addChar()-t írjuk meg. Ahogy fent láttuk a Visual Studio és a QT Creator másképpen működik egy kicsit, ezért a kód is kicsit különböző lesz. void Szamologep::addChar(QChar ch) { QString qs = ui->lineEdit->text() + ch; // QString qs = ui.lineEdit->text() + ch; ui->lineEdit->setText(qs); // ui.lineEdit->setText(qs); }
// QT Creator project // Visual Studio project
Ezután a többi karaktert beíró függvény egyszerű: void void void void void void void void void void void void void void void
Szamologep::on_btn0_clicked() { addChar('0');} Szamologep::on_btn1_clicked() { addChar('1');} Szamologep::on_btn2_clicked() { addChar('2');} Szamologep::on_btn3_clicked() { addChar('3');} Szamologep::on_btn4_clicked() { addChar('4');} Szamologep::on_btn5_clicked() { addChar('5');} Szamologep::on_btn6_clicked() { addChar('6');} Szamologep::on_btn7_clicked() { addChar('7');} Szamologep::on_btn8_clicked() { addChar('8');} Szamologep::on_btn9_clicked() { addChar('9');} Szamologep::on_btnSzor_clicked(){ addChar('*');} Szamologep::on_btnPer_clicked() { addChar('/');} Szamologep::on_btnPlussz_clicked() { addChar('+');} Szamologep::on_btnMinusz_clicked() { addChar('-');} Szamologep::on_btnExp_clicked(){ addChar('E');}
Van azonban egy probléma a btnVesszo gombbal! Nálunk tizedesvessző van, de pl az angolszász országokban tizedespont. A QString::toDouble() függvény, amit a számmá konvertáláshoz használunk majd mindig tizedespontot vár és a QString::setNum() is azt ír be a stringbe, mi pedig tizedesvesszőt használunk. Ezért a btnVesszo gomb is tizedespontot ír be a lineEdit-be10. void Szamologep::on_btnVesszo_clicked() { addChar('.');}
A lineEdit törlése: void Szamologep::on_btnClear_clicked() { ui->lineEdit->clear();}
A +/- gomb csak az exponens szám előjelét változtatja meg, ezért meg kell néznie, hogy a lineEdit nem üres-e, illetve, hogy az E betűvel, vagy utána egy számmal végződik-e és nem szabad semmit csinálnia, ha ezek a feltételek nem teljesülnek: 10
Van olyan függvény is, ami a helyi sajátosságokat is figyelembe veszi, de azt használni nagyon elbonyolítaná a dolgokat.
void Szamologep::on_btnPm_clicked() { QString qs = ui->lineEdit->text(), // eredeti szöveg qsNum; if(qs.isEmpty()) // üres ? return; int i = qs.length()-1; if(qs[i] == 'E') // akkor mindig minusz kell { ui->lineEdit->setText(qs + '-'); return; } // egyébként az E után egy számnak kell állnia for( ; i > 0; --i) if(!qs[i].isDigit()) // szám eleje break; if(qs[i] == '-' || qs[i] == '+') { if(i == 0 || qs[i-1] != 'E') // nem exponens return; // mínuszból plussz lesz, plusszból mínusz qs[i] = qs[i] == '-' ? '+' : '-'; // előjel csere ui->lineEdit->setText(qs + '-'); // visszaírjuk return; } }
A btnEq ugyancsak egy nem üres és számmal kezdődő stringet vár. Először kivágja a számot tartalmazó stringet, majd a toDouble() függvénnyel számmá alakítja (szam1). A kivágásra azért van szükség, mert a toDouble() csak érvényes szám stringeket tud átalakítani, ha bárhol egy rossz karaktert talál a konverzió eredménye 0 lesz11. Ezután kiolvassa a műveleti jelet és a következő számot (szam2), elvégzi a műveletet és az eredményt elrakja szam1-be, keresi a következő műveleti jelet és utána a következő számot, stb. Amikor elfogy a feldolgozandó string a szam1-et visszaírja lineEdit-be. Mivel ez nem egy komplett alkalmazás, ezért a hibakezelést nagyon leegyszerűsítjük: hibás inputra nincs eredmény. Az on_btnEq_clicked() függvény pl a következő lehet: void Szamologep::on_btnEq_clicked() { QString qs; qs = ui->lineEdit->text(); if(qs.isEmpty()) return; int eleje = 0; // innen keressük a következő számot double szam1=0.0, szam2 = 1.0; QChar chMuvelet; // a műveleti jel szam1 = szam(qs, eleje); if(eleje < 0) return; if(eleje == qs.length()) 11
// // // //
első szám. Az eleje a szám utánra mutat vagy ha kisebb, mint 0, akkor hiba volt de nincs jelzés csak egy szám volt beírva, nincs mit tenni
Ez picit jobb, mint az exception, amit a stod() dob ilyen esetben…
return; while(eleje > 0 && eleje < qs.length())// a maradék szöveg feldolgozása { chMuvelet = qs[eleje++]; // műveleti jel szam2 = szam(qs, eleje); // a következő szám if(eleje < 0) // hiba? return; // nincs hibajelzés // elvégezzük a műveletet, ha hiba -> chMuvelet = '!' szam1 = muvelet(szam1, szam2, chMuvelet); if(chMuvelet == '!') // műveleti hiba return; // de nincs jelzés // A következő karakternek (ha van) műveleti jelnek kell lennie } // Az eredmény ui->lineEdit->setText(QString().setNum(szam1));
} Két segédfüggvényt használtunk. Ezeket írjuk be az osztály definíció private szakaszába a szamologep.h-ba is! Egy számot kivágó függvényt (és): double szam(QString str, int &eleje); ami az str-ből eleje-től kezdve kivág egy lebegőpontos számot ábrázoló részt és átalakítja számmá. Visszaadja a számot és az eleje-t beállítja a szám utánra. Ha hiba van a számban (pl. két tizedespont, vagy előjel), akkor eleje -1 lesz, a visszaadott szám pedig 0. Egy, a műveletet elvégző függvényt: double muvelet(double szam1, double szam2, QChar &chMuvelet); Ha a művelet nem végezhető el, akkor a chMuvelet-be egy felkiáltójel kerül. A teljes program tehát a következő fájlokból áll: main.cpp: #include "szamologep.h" #include
int main(int argc, char *argv[]) { QApplication a(argc, argv); Szamologep w; w.show(); return a.exec();
} szamologep.h: #ifndef SZAMOLOGEP_H #define SZAMOLOGEP_H #include
namespace Ui { class Szamologep; } class Szamologep : public QMainWindow { Q_OBJECT public: explicit Szamologep(QWidget *parent = 0); ~Szamologep(); private: Ui::Szamologep *ui; void addChar(QChar digit); double szam(QString str, int &eleje); double muvelet(double szam1, double szam2, QChar &chMuvelet); private slots: void on_btn0_clicked(); void on_btn1_clicked(); void on_btn2_clicked(); void on_btn3_clicked(); void on_btn4_clicked(); void on_btn5_clicked(); void on_btn6_clicked(); void on_btn7_clicked(); void on_btn8_clicked(); void on_btn9_clicked(); void on_btnClear_clicked(); void on_btnSzor_clicked(); void on_btnPer_clicked(); void on_btnPlussz_clicked(); void on_btnMinusz_clicked(); void on_btnVesszo_clicked(); void on_btnPm_clicked(); void on_btnExp_clicked(); void on_btnEq_clicked(); }; #endif // SZAMOLOGEPI_H
szamologep.cpp: #include "szamologep.h" #include "ui_szamologep.h" Szamologep::Szamologep(QWidget *parent) : QMainWindow(parent), ui(new Ui::Szamologep) { ui->setupUi(this); } Szamologep::~Szamologep() { delete ui; } void Szamologep::addChar(QChar ch) {
QString qs = ui->lineEdit->text() + ch; ui->lineEdit->setText(qs); } void void void void void void void void void void void void void void void void
Szamologep::on_btn0_clicked() { addChar('0');} Szamologep::on_btn1_clicked() { addChar('1');} Szamologep::on_btn2_clicked() { addChar('2');} Szamologep::on_btn3_clicked() { addChar('3');} Szamologep::on_btn4_clicked() { addChar('4');} Szamologep::on_btn5_clicked() { addChar('5');} Szamologep::on_btn6_clicked() { addChar('6');} Szamologep::on_btn7_clicked() { addChar('7');} Szamologep::on_btn8_clicked() { addChar('8');} Szamologep::on_btn9_clicked() { addChar('9');} Szamologep::on_btnSzor_clicked(){ addChar('*');} Szamologep::on_btnPer_clicked() { addChar('/');} Szamologep::on_btnPlussz_clicked() { addChar('+');} Szamologep::on_btnMinusz_clicked() { addChar('-');} Szamologep::on_btnVesszo_clicked() { addChar('.');} Szamologep::on_btnExp_clicked(){ addChar('E');}
void Szamologep::on_btnClear_clicked() { ui->lineEdit->clear();} void Szamologep::on_btnPm_clicked() { QString qs = ui->lineEdit->text(), qsNum; if(qs.isEmpty()) // üres return; int i = qs.length()-1; if(qs[i] == 'E') // akkor mindig minusz kell { ui->lineEdit->setText(qs + '-'); return; } // egyébként az E után egy számnak kell állnia for( ; i > 0; --i) if(!qs[i].isDigit()) // szám eleje break; if(qs[i] == '-' || qs[i] == '+') { if(i == 0 || qs[i-1] != 'E') // nem exponens return; // mínuszból plussz lesz, plusszból mínusz qs[i] = qs[i] == '-' ? '+' : '-'; // előjel csere ui->lineEdit->setText(qs + '-'); return; } } double Szamologep::szam(QString str, int &eleje) { if(eleje >= str.length()) { eleje = -1; return 0; } int vege = eleje; if(str[vege] == '-' || str[vege] == '+') // előjel? ++vege; while(vege < str.length()) {
QChar ch = str[vege]; // ch érvényességének ellenőrzése if(QStringLiteral("0123456789E.").indexOf(ch) < 0) break; // persze szemantikusan hibás... Miért? ++vege; } if(vege == eleje) { eleje = -1; // hiba return 0; } // alakítsuk számmá bool ok; // ha hiba van benne, pl két pont, vagy E, vagy előjel, stb double d = str.mid(eleje, vege-eleje).toDouble(&ok); if(!ok) { eleje = -1; return 0.0; } eleje = vege; // a szám utánra return d; } double Szamologep::muvelet(double szam1, double szam2, QChar &chMuvelet) { switch(chMuvelet.unicode()) { case '+': return szam1 + szam2; case '-': return szam1 - szam2; case '*': return szam1 * szam2; case '/': if(szam2 == 0) { chMuvelet = '!'; return 1e308; } else return szam1/szam2; default: chMuvelet = '!'; return 0; } } void Szamologep::on_btnEq_clicked() { QString qs; qs = ui->lineEdit->text(); if(qs.isEmpty()) return; int eleje = 0; // innen keressük a következő számot double szam1=0.0, szam2 = 1.0; QChar chMuvelet; // a műveleti jel szam1 = szam(qs, eleje); if(eleje < 0) return; if(eleje == qs.length())
// // // //
első szám. Az eleje a szám utánra mutat vagy ha kisebb, mint 0, akkor hiba volt de nincs jelzés csak egy szám volt beírva, nincs mit tenni
return; while(eleje > 0 && eleje < qs.length())// a maradék szöveg feldolgozása { chMuvelet = qs[eleje++]; // műveleti jel szam2 = szam(qs, eleje); // a következő szám if(eleje < 0) // hiba? return; // nincs hibajelzés // elvégezzük a műveletet, ha hiba -> chMuvelet = '!' szam1 = muvelet(szam1, szam2, chMuvelet); if(chMuvelet == '!') // műveleti hiba return; // de nincs jelzés // A következő karakternek (ha van) műveleti jelnek kell lennie } // Az eredmény ui->lineEdit->setText(QString().setNum(szam1)); }