5. diel - Jednoduchá kalkulačka v Qt a C ++ - Layout
V minulej lekcii, Reťazca v Qt - QString a QChar , sme niečo povedali o reťazcoch v Qt a v C ++. Dnes začneme tvoriť už nejakú zaujímavejšie aplikáciu, veľmi jednoduchú kalkulačku. Bude mať dve vstupné polia a štyri základné operácie: násobenie, delenie, sčítanie a odčítanie.
Dnes nám bude stačiť obyčajné okno bez toolbarov, menu, stavového
riadku a takých podobných vymožeností:-) Qt je založené na architektúre MVC, teda
presnejšie povedané na architektúre Model - View
, pretože
pohľad zastupuje aj funkciu Controller - spracovanie
požiadaviek. Ak ste sa s touto architektúrou ešte nestretli, dôležité
je, že oddeľujeme kód logiky aplikácie (v našom prípade teraz trieda s
výpočtami pre kalkulačku) od prezentácie, čo je v našom prípade kód
definujúce a obsluhujúci formulár. Nikdy teda nebudeme vykonávať
nič zložité priamo v súbore s formulárom, ale iba tu prevoláte metódy
nejaké ďalšie triedy, v ktorej bude ďalší kód umiestnený.
Návrh aplikácie
Celý návrh môžeme urobiť niekoľkými spôsobmi:
- Od modelu - teda prvýkrát navrhnúť, čo bude základ logiky, a to potom zobraziť vo formulári.
- Od view - pohľadu: teda preskúmať, čo budeme zobrazovať, a potom si k tomu urobiť logickú časť.
- Od každého niečo - postupne niečo zobraziť. Potom urobiť kus logiky, zas to zobraziť, alebo aj opačne.
Tu som zvolil druhú variantu. Vytvoríme si najprv kompletné okno a jeho rozvrhnutie, čím sa rozhodneme, čo kde má byť zobrazené. Až potom, v budúcej lekcii, si vytvoríme triedu, ktorá nám potrebné dáta poskytne, keď o ne požiadame.
Návod na použitie aplikácie
Kalkulačka bude fungovať takto:
- Zadáme celé číslo do jedného potom do druhého vstupného poľa
- Zvolíme operáciu medzi číslami
- Zvolíme číselnú sústavu na zobrazenie
- Stlačíme tlačidlo pre výsledok. Ten sa ukáže, ak nenastala chyba. Pri
chybe zadaní, alebo iné chybe, sa zobrazí krátky dialóg pomocou
QMessageBox
.
Založenie projektu
Projekt tentoraz založíme len na QWidget
, ktorý môžeme
použiť aj ako základ aplikácie. Skoršie lekcie mali za úlohu ukázať
základ komplexné aplikácie az čoho sa skladá celé okno, preto sme v nich
použili QMainWindow
. V kalkulačke však nebudeme potrebovať
menu, toolbar a iné veci. Práve preto radšej použijeme QWidget
,
ktorý bude fungovať ako plnohodnotné okno aj s ikonou, titulkom, frontom
udalostí a všetkým potrebným.
Nový projekt už založiť vieme. Len v jednej chvíli to chce maličkú
zmenu. Predovšetkým si pomenujeme triedu okna Kalkulacka
, hlavne
žiadna diakritické znamienka, a QMainWindow
zmeníme na
QWidget
:
Tiež som si pre vás pripravil ikonu okna:
Tú už tiež vieme nastaviť. Pridáme nový súbor Qt - Resource. Pokojne si ikonu môžete stiahnuť a použiť. Alebo si urobiť svoju či nájsť inú vhodnú. Inak je postup vlastne rovnaký ako v predchádzajúcich lekciách.
Návrh používateľského rozhrania
Som zo starej školy a rád používam papier a ceruzku. Proste keď chcem urobiť nejakú grafiku v programe, tak si ju nakreslím na papier a potom sa rozhodnem aká technika na to bude najlepšie. Ani tu to nebude inak:
Keď som sa dlho pozeral na obrázok vyššie, došlo mi, že tabuľka
(mriežka) je úplne ideálny pre rozvrhnutie všetkých prvkov. Použijeme teda
QGridLayout
.
Je to veľmi flexibilný rozvrhnutie. Každý prvok má svoju vlastnú "bunku",
avšak môže ich mať aj niekoľko - ako v riadku tak i v stĺpci. Tiež je
možné nastaviť aj rôzne medzery medzi bunkami. Výsledný formulár pre
kalkulačku bude potom vyzerať nasledovne:
Nemohol som odolať a preto výsledok budeme zobrazovať ako na naozajstnom
segmentovom displeji kalkulačky. Je pravda, že ovládací prvok QLCDNumber
vie
zobraziť len celé čísla, zato v niekoľkých sústavách - šesťnástková,
decimálna, osmičková a binárne. Toho predsa musíme tiež využiť, preto
pridáme aj štyri prepínače - QRadioButton
,
ktoré umožní zmeniť zobrazenie pre danú číselnú sústavu.
Aby sme nemuseli riešiť, aké číslo alebo text používateľ zadal,
použijeme pre každý operand (číslo) zvláštne vstup. Ten bude bohužiaľ
len textový QLineEdit
, z
ktorého získame reťazec QString
, teda aj tak si budeme musieť
zabezpečiť, aby užívateľ naozaj vložil celé číslo a nie čosi
podivného.
Dlho som rozmýšľal, či pre voľbu operácie použiť tlačidlá, zoznam
alebo rozbaľovací zoznam - ComboBox... Výhra padla opäť na
RadioButton, užívateľsky je to pre tento účel prívetivé. Lenže
tu budeme mať dve sady prepínačov a Qt všetko, čo sa definuje v
jednom kontexte, berie, že to k sebe patria. Teda tieto dve skupiny musíme od
seba oddeliť. K tomu doslova nabáda trieda QButtonGroup
.
Pre zobrazenie výsledku výpočtu bude potom najlepšie obyčajné tlačidlo.
Kalkulacka.h
Najprv si modifikujeme hlavičkový súbor kalkulačky, kde doplníme
potrebné ukazovatele. Inak si myslím, že v tomto súbore nie je extra čo
vysvetľovať. O všetkých použitých triedach si ešte podrobnejšie povieme
pri súbore kalkulacka.cpp
. Obsah kalkulacka.h
je
nasledujúci:
#ifndef KALKULACKA_H #define KALKULACKA_H #include <QWidget> #include <QGridLayout> #include <QLCDNumber> #include <QRadioButton> #include <QButtonGroup> #include <QLineEdit> #include <QPushButton> class Kalkulacka : public QWidget { Q_OBJECT public: Kalkulacka(QWidget *parent = 0); ~Kalkulacka(); QGridLayout *mainLayout; QLCDNumber *display; QRadioButton *btnDec; QRadioButton *btnHex; QRadioButton *btnOct; QRadioButton *btnBin; QButtonGroup *numeralButtons; QLineEdit *leftOperand; QLineEdit *rightOperand; QRadioButton *btnPlus; QRadioButton *btnMinus; QRadioButton *btnTimes; QRadioButton *btnDivide; QButtonGroup *operationButtons; QPushButton *btnEqual; }; #endif // KALKULACKA_H
Kalkulacka.cpp
Rovno prejdeme aj do súboru s implementáciou a vložíme do neho nasledujúci kód, ktorý si vzápätí vysvetlíme:
#include "kalkulacka.h" #include <QIcon> Kalkulacka::Kalkulacka(QWidget *parent) : QWidget(parent) { mainLayout = new QGridLayout(); display = new QLCDNumber(); mainLayout->addWidget(display, 1, 1, 1, 4); btnHex = new QRadioButton("HEX", this); btnDec = new QRadioButton("DEC", this); btnOct = new QRadioButton("OCT", this); btnBin = new QRadioButton("BIN", this); numeralButtons = new QButtonGroup(); mainLayout->addWidget(btnDec, 2, 1); mainLayout->addWidget(btnHex, 2, 2); mainLayout->addWidget(btnBin, 2, 3); mainLayout->addWidget(btnOct, 2, 4); numeralButtons->addButton(btnHex); numeralButtons->addButton(btnDec); numeralButtons->addButton(btnOct); numeralButtons->addButton(btnBin); leftOperand = new QLineEdit(); rightOperand = new QLineEdit(); mainLayout->addWidget(leftOperand, 3, 1, 1, 2); mainLayout->addWidget(rightOperand, 3, 3, 1, 2); btnPlus = new QRadioButton("+", this); btnMinus = new QRadioButton("-", this); btnTimes = new QRadioButton("*", this); btnDivide = new QRadioButton("/", this); operationButtons = new QButtonGroup(); operationButtons->addButton((btnPlus)); operationButtons->addButton((btnMinus)); operationButtons->addButton((btnTimes)); operationButtons->addButton((btnDivide)); mainLayout->addWidget(btnPlus, 4, 1); mainLayout->addWidget(btnMinus, 4, 2); mainLayout->addWidget(btnTimes, 4, 3); mainLayout->addWidget(btnDivide, 4, 4); btnEqual = new QPushButton(tr("Spočítej")); mainLayout->addWidget(btnEqual, 5, 1, 1, 4); setLayout(mainLayout); btnDec->setChecked(true); btnPlus->setChecked(true); } Kalkulacka::~Kalkulacka() { if (btnEqual != NULL) { delete btnEqual; } if (operationButtons != NULL) { delete operationButtons; } if (btnPlus != NULL) { delete btnPlus; } if (btnMinus != NULL) { delete btnMinus; } if (btnTimes != NULL) { delete btnTimes; } if (btnDivide != NULL) { delete btnDivide; } if (leftOperand != NULL) { delete leftOperand; } if (rightOperand != NULL) { delete rightOperand; } if (numeralButtons != NULL) { delete numeralButtons; } if (btnHex != NULL) { delete btnHex; } if (btnDec != NULL) { delete btnDec; } if (btnBin != NULL) { delete btnBin; } if (btnOct != NULL) { delete btnOct; } if (mainLayout != NULL) { delete mainLayout; } setWindowIcon(QIcon(":/img/mainIcon")); resize(640, 480); }
Na úplnom začiatku sme vytvorili objekt tabuľkového layoutu a
následne objekt LCD a umiestnili ho do layoutu pomocou
mainLayout->addWidget(display, 1, 1, 1, 4);
. Tu stojí za
všimnutie parametre, ktorý mi sú:
- ukazovateľ na widget
- riadok v tabuľke - počítané od
1
don
- stĺpik v tabuľke - opäť od
1
don
- počet zlúčených riadkov, cez ktoré má ovládací prvok presahovať
(pre hodnotu
1
sa nič nestane) - počet zlúčených stĺpcov, tu teda prvok zaberie
4
stĺpce
Potom vyrobíme prvú skupinu prepínačov pre prechody z jednej číselnej
sústavy do druhej a umiestnime ju do layoutu pomocou
mainLayout->addWidget(btnDec, 2, 1);
... Tak pridáme aj skupiny
tlačidiel: operationButtons->addButton((btnPlus));
... Tu si
možno všimnúť, že dva parametre sme vynechali, pretože nie sú potrebné a
Qt nám to umožňuje. Jednoducho len volíme riadok a stĺpec.
Pre istotu znovu pre zapamätanie: QGridLayout
si svoje pozície čísluje od jednotky, nie od
nuly ako pole v C.
leftOperand = new QLineEdit();
a
rightOperand = new QLineEdit();
sú dve dôležité editačné
políčka na vloženie dvoch vstupných čísel. Samozrejme je hneď umiestnime
do "tabuľky" rozloženie prvkov ako
mainLayout->addWidget(leftOperand, 3, 1, 1, 2);
. Každé z nich
bude zaberať polovicu riadku, teda 2
stĺpce.
Nasledujú "prepínače" pre početné operácie. Tu asi nie je tiež nie je veľmi čo vysvetľovať, pretože je to rovnaký postup, ktorý bol použitý u * prepínačov "číselných sústav.
Celý layout nakoniec vložíme do widgetu pomocou
setLayout(mainLayout);
a pre istotu, aby bolo jasné, že
počítame v dekadickej sústave a základné operácie je sčítanie,
nastavíme dané prepínače ako aktívny / zapnutej:
btnDec->setChecked(true);
a
btnPlus->setChecked(true);
A úplne na koniec si nastavíme ikonu a veľkosť okna:
setWindowIcon(QIcon(":/img/mainIcon")); resize(640, 480);
Ako posledný máme tlačidlo pre výpočet. Také už sme robili skoro na začiatku kurzu. Avšak tu je drobná zmena, ktorá asi bude neskôr dosť dôležitá a myslím, že sa z nej stane aj dosť dobrý zvyk.
Medzinárodné rozhranie
btnEqual = new QPushButton(tr("Spočítej"));
Na kódu vyššie je samozrejme zaujímavé použitie funkcie
tr(QString)
. Tá sa dá vyložiť ako: Prelož reťazec. Teda ak
všetky reťazce budeme uzatvárať do tejto funkcie, máme aplikáciu
pripravenú k prípadným viacjazyčným mutáciám. Počas kurzu si tieto
možnosti ešte predstavíme.
Záver
Tým máme hotové rozvrhnutie aplikácie. Pokojne si ju preložte a spustite. Síce nič zatiaľ nerobí, ale vyzerá pekne:-)
Nabudúce, v lekcii Jednoduchá kalkulačka v Qt a C ++ - Model , si vytvoríme jednoduchý model. Síce je kalkuačka jednoduchá, ale pracujeme v MVC (MV) frameworku, tak by bolo dobré dodržať túto architektúru. Naozaj sa bude hodiť neskôr, keď si osvojíme dobré návyky čo najskôr. Nabudúce tiež ošetríme užívateľské vstupy a sprevádzkujeme prepínače.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 79x (12.46 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C++