Archiv pro štítek: Label

Qt – Combo box

Na následujícím příkladě si společně ukážeme práci s combo boxem. Konkrétně budeme využívat rovnou dva ovládací prvky tohoto typu, které na sobě dokonce budou závislé. Změna volby uživatelem se proto okamžitě projeví v obsahu druhého combo boxu. Pokud nastavíme vlastnost editable na true, získáme možnost vkládat vlastní hodnoty. V našem programu však povolíme výběr pouze z předem definovaných údajů. Nejprve se aplikace zeptá, zda-li budeme cestovat po zemi nebo ve vzduchu. Na základě odpovědi poté upraví druhý combo box a nabídne odpovídající dopravní prostředky.

Combo box

Designérský režim

Po vytvoření projektu se přepneme do módu design. Postupně přidáme oba combo boxy a několik Labelů. Nezapomeňte si jednotlivé objekty vhodně pojmenovat, díky čemuž si usnadníte následující programování.

Tvorba zdrojového kódu

Mezi pro nás nejdůležitější funkci combo boxu patří addItem. V konstruktoru třídy si s její pomocí naplníme ovládací prvek. Položky se přidávají vždy za poslední volbu a disponují rovněž vlastním interním id, které se počítá od nuly. To ostatně vysvětluje, proč jsem vytvořil i pomocnou funkci procistit. Původně přitom její tělo obsahovalo iterační cyklus, včas mě však zarazila hodnota vrácená s pomocí count. Ta totiž prozrazuje celkový počet záznamů a nikoliv nejvyšší id. Tuto hodnotu si musíme sami dopočítat, tedy odečíst jedničku. Procistit musíme zavolat po každé změně výběru, protože v opačném případě by se druhý combo box postupně rozrůstal o duplicitní informace. Spojení signálů a slotů pochopitelně naleznete opět v konstruktoru. Volají se v podstatě jen dvě funkce – zmena a souhrn. Ta první se postará o obměnu příslušného combo boxu. Druhá nám sestaví informační QString, který poté nastaví vlastnosti text u Labelu umístěného ve spodní části okna. Povšimněte si rovněž, že se plně obejdeme bez tlačítek. Veškeré úpravy probíhají ihned poté, co uživatel změní svůj názor.

#include „widget.h“
#include „ui_widget.h“

Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);

ui->cb_typCesty->addItem(„Po zemi“);
ui->cb_typCesty->addItem(„Ve vzduchu“);

connect(ui->cb_typCesty,SIGNAL(activated(int)),this,SLOT(zmena(int)));
connect(ui->cb_typCesty,SIGNAL(activated(int)),this,SLOT(souhrn()));
connect(ui->cb_dopravniProstredek,SIGNAL(activated(int)),this,SLOT(souhrn()));
zmena(ZEME);
souhrn();

}

Widget::~Widget()
{
delete ui;
}

void Widget::zmena(int id){
procistit(ui->cb_dopravniProstredek);

if (id == ZEME){
ui->cb_dopravniProstredek->addItem(„Automobil“);
ui->cb_dopravniProstredek->addItem(„Motocykl“);
}else if (id == VZDUCH){
ui->cb_dopravniProstredek->addItem(„Letadlo“);
ui->cb_dopravniProstredek->addItem(„Helikoptéra“);
}
}

void Widget::procistit(QComboBox*& obj){
while(obj->count() != 0){
obj->removeItem(obj->count()-1);
}

}

void Widget::souhrn(){
QString typ = ui->cb_typCesty->itemText(ui->cb_typCesty->currentIndex());
QString prostredek = ui->cb_dopravniProstredek->itemText(ui->cb_dopravniProstredek->currentIndex());
QString vysledek = „Typ cesty: „+ typ +“. Dopravní prostředek: “ + prostredek;
ui->l_vysledek->setText(vysledek);
}

 

Enum

Závěrem ještě poukáži na výčtový typ pojmenovaný překvapivě jako TYP. Konstanta ZEME zastupuje číselnou hodnotu 0, zatímco VZDUCH symbolizuje 1. Zdrojový kód díky tomu získává na přehlednosti.

#ifndef WIDGET_H
#define WIDGET_H

#include
#include

#include

enum TYP{ZEME,VZDUCH};

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
Q_OBJECT

public:
explicit Widget(QWidget *parent = 0);
~Widget();

public slots:
void zmena(int);
void souhrn();

private:
Ui::Widget *ui;
void procistit(QComboBox*& obj);
};

#endif // WIDGET_H

 

Qt – checkbox

Před praktickou ukázkou práce s checkboxy si nejprve dovolím malé shrnutí rozdílů mezi tímto ovládacím prvkem a radio buttonem. Zatímco u první zmíněné varianty může uživatel zaškrtnout více voleb, v případě té druhé je jeho svoboda značně omezena. Zvolí totiž pouze jen jednu položku. Z tohoto důvodu se práce s oběma prvky poněkud liší. Checkbox nám totiž pochopitelně vrátí předem nespecifikovaný počet výsledků. Proto se dnes zaměříme právě na tuto oblast zajímavou z programátorského hlediska.

Poměrně dlouho jsem přemýšlel, jaký příklad pro tuto problematiku zvolit. Nakonec došlo ke stvoření jednoduché aplikace, která nás vybízí k výběru několika druhů sýra. Po stisknutí na tlačítko nám následně všechny zvolené potraviny vypíše. Po dalším rozšíření by tento program mohl například využívat kuchař v pizzerii, který si přesně nepamatuje, co si zákazníci vlastně objednali. :-)

Qt checkbox - před zadáním

Qt checkbox - po zadání

#ifndef WIDGET_H
#define WIDGET_H

#include
#include

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
Q_OBJECT

public:
explicit Widget(QWidget *parent = 0);
~Widget();

private:
Ui::Widget *ui;
QButtonGroup *syr_skupina;

public slots:
void syr();
};

#endif // WIDGET_H

 

#include „widget.h“
#include „ui_widget.h“

Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);

syr_skupina = new QButtonGroup(this);
syr_skupina->addButton(ui->ch_hermelin,1);
syr_skupina->addButton(ui->ch_eidam,2);
syr_skupina->addButton(ui->ch_mozzarella,3);
syr_skupina->setExclusive(false);

}

Widget::~Widget()
{
delete ui;
}

void Widget::syr(){
QAbstractButton *vracene;
QString vysledek = „Objedávka: \n“;
int pocet = 0;

for(int i = 1; i < 4;i++){
vracene = syr_skupina->button(i);
if (vracene->isChecked()){
vysledek += vracene->text() + „\n“;
pocet++;
}
}

if(pocet == 0){
vysledek += „Není vybrán žádný sýr!“;
}else{
vysledek += „Přejeme dobrou chuť!“;
}

ui->l_vysledek->setText(vysledek);
}

 

Skupina prvků v podání QbuttonGroup

V návrhářském režimu stačí přidat několik popisných labelů a samotné checkboxy. Nezapomeňte rovněž na ovládací prvek, ve kterém se zobrazí získaný výsledek. V našem případě se opět jedná o klasický label. Zajímavější kroky na nás čekají v konstruktoru. Vytvoříme si totiž skupinu prvků tzv. QbuttonGroup a přidáme do ní jednotlivé checkboxy. Musíme u nich specifikovat i vlastní id, které později budeme potřebovat při procházení v iteračním cyklu. S pomocí setExclusive dosáhneme toho, že se celá skupina začne chovat dle našich požadavků. Pokud bychom jako parametr předali true, získáme checkboxy fungující jako radio buttony.

Zpracování

Ve slotu, který se spouští po signálu clicked z tlačítka se provádí samotný výpis. V cyklu si projdeme jednotlivé checkboxy a ověříme si, zda je uživatel zaškrtnul. Pokud ano, přidáme jejich popisek (text) do stringové proměnné, kterou nakonec nastavíme s pomocí setText výslednému labelu v hlavním okně.

Qt – signály a sloty

V následujícím tutoriálu vám ukáži jeden ze způsobů, kterým lze vzájemně propojovat prvky přidané v návrhářském (designérském) režimu. Našim cílem bude v tomto případě vytvořit jednoduché okno s jediným tlačítkem (Push Button). Po kliknutí se následně zobrazí text, který byl původně skrytý.

Přípravy

Nejprve si přidáme do prostoru okna dva potřebné elementy. Jde o již zmíněné tlačítko a popisek (Label). Nezapomeňte vždy zadat vhodné objectName, což nám usnadní život při samotném programování. V případě objektu třídy QLabel rovněž nastavte vlastnost text na nějakou pěknou větu, kterou po kliknutí uživatele překvapíme. Pokud si nyní celý projekt zkompilujete a spustíte, zaskočí vás, že tento řetězec se v okně vyskytuje. Abychom tomu zabránili a vytvořili tak dojem skrytého prvku, zavoláme v konstruktoru naší třídy odpovídající funkci hide().

Okno před kliknutím

Okno před kliknutím

 

Okno po kliknutí

Okno po kliknutí

Propojení signálu se slotem

Nyní již vše funguje tak jak má. Po inicializaci programu můžete pouze kliknout na tlačítko. To však pochopitelně momentálně neví, co má v případě signálu clicked() vykonat. K tomuto účelu musíme vytvořit v úvodu nastíněné propojení. Učiníme tak opět v konstruktoru s pomocí funkce connect. Povšimněte si vyžadovaných parametrů. Nejprve specifikujeme objekt, který odesílá signál. Následně již přijde na řadu jeho konkretizace. Poté pokračujeme zadáním příjemce. V našem případě se zde nachází slovíčko this, protože slot uvedený jako poslední patří do stejné třídy, ze které je volána funkce connect. Sloty si tak ve své podstatě můžete představit jako naprosto běžné funkce, které vykonávají vámi určené věci. K jejich zavolání přitom slouží právě signály, které mnoha způsoby produkují objekty přidané v návrhářském režimu.

#include „okno.h“
#include „ui_okno.h“

okno::okno(QWidget *parent) :
QWidget(parent),
ui(new Ui::okno)
{
ui->setupUi(this);

ui->l_text->hide();

connect(ui->pb_text,SIGNAL(clicked()),this,SLOT(zobraz()));
}

okno::~okno()
{
delete ui;
}

void okno::zobraz(){
ui->l_text->show();
}

Rád bych vás dále upozornil na pár řádků kódu v hlavičkovém souboru třídy. Jde především o sekci public slots: (pozor na zrádné a zpočátku opomíjené ‚s‚ na konci!). Zde se uvádí deklarace slotů, které bude program využívat.

#ifndef OKNO_H
#define OKNO_H

#include

namespace Ui {
class okno;
}

class okno : public QWidget
{
Q_OBJECT

public:
explicit okno(QWidget *parent = 0);
~okno();

private:
Ui::okno *ui;

public slots:
void zobraz();
};

#endif // OKNO_H