IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

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:

Grafické rozloženie QMainWindow - Qt - Okenné / formulárové aplikácie v C ++

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);
Pozornosť venujte destruktor okná - všetky objekty vytvorené pomocou operátora 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ť:

Qt Tlačidlo v C ++ - Qt - Okenné / formulárové aplikácie v C ++

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 makra qApp.
  • Metóda connect, ktorá je definovaná v základnej triede QObject, prepája signály a sloty. Hovorí, že tlačidlo spolu so signálom clicked() chceme spojiť s aplikáciou a jej slotom quit().
  • 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++

 

Predchádzajúci článok
Prvé okno v Qt a C ++
Všetky články v sekcii
Qt - Okenné / formulárové aplikácie v C ++
Preskočiť článok
(neodporúčame)
Reťazca v Qt - QString a QChar
Článok pre vás napísal Virlupus
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje webovým aplikacím, skladově-účetnímu softwaru, 3D grafice, lexiální analýze a parserování. Studuje fyziku na MFF UK. Učil IT na střední škole.
Aktivity