3. diel - Dokončenie prvého okna v Qt a C ++ - Tlačidlo
V minulej lekcii, Prvé okno v Qt a C ++ , sme si vytvorili svoju prvú formulárové aplikáciu v Qt frameworku pre C ++. V dnešnom Qt tutoriálu do nášho prázdneho okna vložíme prvý komponent, ktorú bude tlačidlo, ktoré po kliknutí okno zavrie.
Rozloženie okna
Pre túto úlohu si však musíme viac povedať o QMainWindow
,
hlavne o jeho vnútornom grafickom rozložení. To demonštruje diagram
nižšie:
Všimnite si, že okno sa delí na päť základných oblastí:
- Prvý a posledný je určená pre hlavnú ponuku a stavový riadok.
- Medzi mini je oblasť pre panely nástrojov, kde jeden toolbar môžete posúvať (myšou alebo programovo) dookola, prípadne štyri panely umiestniť po všetkých stranách alebo rôzne experimentovať s ich rozmiestnením v tejto oblasti.
- Ďalšia časť dock widgets je určená rôzne doplňujúce widgety, ktoré majú byť trvalo súčasťou okna. Túto možnosť som zatiaľ nijako moc nevyužil, snáď len pokusne. To však neznamená, že sa k nej podrobnejšie nedostaneme.
- Posledné súčasť Hlavného Okna je centrálna widget. Tu sa bude odohrávať všetko podstatné, lebo práve tu je miesto pre GUI, teda grafické užívateľské rozhranie našej aplikácie.
Widget a manažérov rozloženie
Aby sme mohli do okna niečo pridať, je potrebné si vytvoriť teda
centrálnej pomocný widget. Použijeme úplne základné QWidget
, od ktorého
sú odvodené všetky ostatné grafické (ai ďalšie) časti aplikácie.
Manažérov rozloženie
Ďalšou dôležitou informáciou je, že Qt využíva systém
manažérov rozloženie - layouty, ktoré vydajú na samostatnú
lekciu. Kdychom totiž komponenty vo formulári umiestnili na absolútne
súradnice, okno by nereagovalo na zväčšenie / zmenšenie alebo dokonca na
zmenu rozlíšenia alebo DPI. Layouty umožňujú komponenty na formulári
automaticky usporadúvať a každý to robí rôznym spôsobom (napr. Vedľa
seba alebo do tabuľky). My dnes použijeme tzv. QHBoxLayout
,
ktorý komponenty skladá vedľa seba a prípadne ich zalomia na ďalší
riadok, ak na formulári už na ďalší nie je miesto.
Pridanie tlačidla do projektu
Otvoríme teda minulý projekt s oknom, aby sme nemuseli začínať odznovu, a trochu si ho poupravíme.
Mainwindow.h
Do hlavičkového súboru pridáme pomocný widget, spomínaný layout a potom aj samotné tlačidlo:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QPushButton> #include <QHBoxLayout> #include <QWidget> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = 0); ~MainWindow(); QWidget * central; QHBoxLayout *layout; QPushButton *cudlik; };
Triede sme pridali nasledujúce atribúty:
QPushButton
- Tlačidlo.QHBoxLayout
- Jednoduchý layout, ktorý jednotlivé prvky skladá vedľa seba do riadky a keď je riadok plná, jednoducho prejde na ďalšie. Layouty sú spôsob, akým komponenty na formuláre umiestňujeme. V našom prípade len jedného tlačidla by sme mohli použiť pokojne aj niektorý iný.QWidget
- Komponent nám poslúži ako obsah centrálnej časti hlavného okna. Pri rozsiahlejších programoch by sme si pre neho vytvorili samostatnú triedu. Zatiaľ to však nie je nutné.
Mainwindow.cpp
Prejdeme do súboru mainwindow.cpp
a inicializujeme tu
ukazovatele na všetky tri inštancie a ešte vykonáme niekoľko úprav, ktoré
si hneď popíšeme. Výsledný kód súboru vyzerá takto:
#include "mainwindow.h" #include <QIcon> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { resize(640,480); setWindowTitle("Můj první program"); /* setToolTip("Toto okno nic nedělá"); */ setWindowIcon(QIcon(":/img/mainIcon")); central = new QWidget(this); layout = new QHBoxLayout(); central->setLayout(layout); cudlik = new QPushButton("Zavři mě"); cudlik->setToolTip("Zavřu celé okno!!!"); layout->addWidget(cudlik); setCentralWidget(central); } MainWindow::~MainWindow() { if (cudlik != NULL) { delete cudlik; } if (layout != NULL) { delete layout; } if (central != NULL) { delete central; } }
V kóde vykonávame nasledujúce:
- Vytvoríme si inštanciu widgetu a layoutu:
central = new QWidget(this);
,layout = new QHBoxLayout();
- Nášmu widgetu nastavíme daný layout:
central->setLayout(layout);
- Ďalej potrebujeme ono dôležité tlačidlo a zároveň mu pridelíme text
(možno napríklad aj ikonu):
cudlik = new QPushButton("Zavři mě");
Ak chcete, môžete tlačidlo doplniť aj o rýchlu nápovedu:cudlik->setToolTip("Zavřu celé okno!!!");
- Tlačidlo umiestnime do layoutu. Pretože je len jedno a nemá nastavenú
veľkosť, tak vyplní celú šírku okna:
layout->addWidget(cudlik);
- Posledný krok je náš widget umiestniť do centrálnej oblasti okna:
setCentralWidget(central);
new
sú po teste na ich existenciu poctivo zmazané
operátorom delete
. Berme to ako nutný zvyk, aby nedochádzalo k
zaplneniu pamäte, ktorá síce nikomu už nepatrí, ale už sa nedá alokovať.
Proste akonáhle niekde použijete new
, radšej okamžite v
destruktor zapíšte príkaz pre zrušenie objektu. Osobne viem, že ak to
neurobím hneď, môže sa stať, že zabudnem.
Tak to je celé. Môžeme vyskúšať:
Tlačidlo ešte samozrejme po kliknutí nič neurobí.
Reakcia kliknutie na tlačidlo
Naším prianím bolo, aby tlačidlo po stlačení zavrelo okno. Tu sa
dostávame k mimoriadne silnému nástroju, ktorý sa nazýva signály a
sloty. O čo kráča? Každá trieda odvodená od QObject
môže
posielať a prijímať správy (informácie o udalostiach) z ďalších tried a
reagovať na ne. Dokonca je možný obojstranný prenos.
Signály
Pre naše tlačidlo existuje už preddefinovaný signál v rodičovskej
triede QAbstractButton
.
Nás bude zaujímať signál clicked(bool checked = false)
, ktorý
je vyvolaný ak na komponent bolo kliknuté. V iných programovacích jazykoch
sa tomuto mechanizmu často hovorí udalosti.
Trochu problém je v tom, že signál sa len zaradí do fronty udalostí a potom už je mu jedno čo sa s ním stane. To je naša starosť, aby bol správne spracovaný.
Sloty
My potrebujeme, aby signál prijala aplikácie. K tomu nám pomôže trieda
QApplication
,
ktorá je odvodená od QCoreApplication
a obsahuje slot (možný príjemca signálu) quit()
, ktorý
aplikáciu ukončí.
Mainwindow.cpp
Teraz je nutné programu oznámiť, že má tento signál aj slot prepojiť. Myslím, že uviesť len dva danej riadky kódu bude stačiť:
// mainwindow.cpp ... #include <QApplication> ... connect(cudlik, SIGNAL(clicked()), qApp, SLOT(quit()), Qt::QueuedConnection);
Čo sme to vlastne urobili?
- Vložením knižnice
QApplication
sme získali možnosť prístupu k unikátnemu ukazovateľmi na celú aplikáciu pomocou makraqApp
. - Metóda
connect
, ktorá je definovaná v základnej triedeQObject
, prepája signály a sloty. Hovorí, že tlačidlo spolu so signálomclicked()
chceme spojiť s aplikáciou a jej slotomquit()
. Qt::QueuedConnection
je taká dobrá prax, ktorá umožní radiť udalosti do fronty. Inak by sa mohlo stať, že aplikácia ešte niečo potrebuje dokončiť a pri ukončení by to nestihla. Potom treba prídete o nejaké dáta, uloženie konfigurácie atp.
Tak a máme to celé, stačí preložiť spustiť a vyskúšať, že
aplikácia naozaj funguje. Nabudúce, v lekcii Reťazca v Qt - QString a QChar , si predstavíme triedu
QString
, ktorá sa nám bude v ďalších lekciách hodiť.
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é 89x (81.75 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C++