Archiv pro rubriku: Qt

Qt – čtení ze souboru

V jednom z dalších tutoriálů týkajících se zaměříme na získání dat uložených ve formě textu a následné zobrazení v okně. Nejprve uživatele vyzveme k výběru požadovaného souboru, díky čemuž získáme potřebou cestu. Následně informace lehce poupravíme a výsledek budeme prezentovat s pomocí prvku textEdit.

Qt - načtený soubor

Zpracování údajů po řádcích

Záměrně jsem se rozhodl nenačíst celý soubor najednou, ale postupovat po částech. Získáme tak jednotlivé řádky, se kterými můžeme dále pohodlně pracovat. Pakliže by například soubor obsahoval čísla, musíme vždy každý údaj nejprve převést, aby jej šlo uchovat v proměnné typu int či double. V našem případě však vyzkoušíme něco jiného. Jednotlivé záznamy obalíme tagem H3 a výsledek textEdit dostane v HTML formě. Zcela jednoduše lze proto s textem provádět mnoho činností – změnu barvy, transformaci v tučný záznam a podobné úpravy.

#include „mainwindow.h“
#include „ui_mainwindow.h“

#include
#include
#include
#include

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

setCentralWidget(ui->textEdit);

setWindowTitle(„Načtení souboru“);

connect(ui->action_Nacist_soubor,SIGNAL(triggered()),this,SLOT(nacti_soubor()));
connect(ui->action_Konec,SIGNAL(triggered()),this,SLOT(close()));
}

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

void MainWindow::nacti_soubor()
{
QString cesta = QFileDialog::getOpenFileName(this,“Zvolte soubor“,“/home“,“Textový soubor (*.txt);;Všechny soubory(*.*)“);

if(cesta.isNull())
{
QMessageBox::warning(this,“Varování“,“Nebyl vybrán žádný soubor k načtení“);
}
else
{
QFile soubor(cesta);
soubor.open(QIODevice::ReadOnly | QIODevice::Text);

QTextStream stream(&soubor);
stream.setCodec(„utf-8″);
QString radek,vysledek;

while(!stream.atEnd())
{
radek = soubor.readLine();
//V proměné radek máme načtená řádek ze souboru a můžeme s ním provádět další operace
vysledek += „

„+radek+“

\n“;

}
ui->textEdit->insertHtml(vysledek);
}
}

Rád bych upozornil na fakt, že okno sloužící k výběru souboru můžeme vyšperkovat k představám programátora. Dozajista využijete specifikování typů povolených koncovek. Činí se tak v jednom z parametrů a to díky stringovému řetězci. Jednotlivé akceptovatelné varianty odděluje dvojice středníků. Dále určujeme i výchozí složku. Protože požívám Linux, vidíte ve zdrojovém kódu /home. Lidé preferující operační systém Windows mohou směle uvést např. C:\data.

Pozor na jednu skutečnost. Uživatel má možnost dialog zjišťující cestu kdykoliv ukončit a my poté pochopitelně nemůžeme žádný soubor načíst. Ošetření vyřeší jednoduchá podmínka testující, zda proměnná cesta obsahuje daný řetězec. Pakliže ano, vše je v pořádku a můžeme programu dovolit vykonat činnost, ke které ho vytváříme. V opačném případě raději vypíšeme hlášku a uživateli pochopitelně umožníme se o zvolení cesty pokusit kdykoliv později.

Povšimněte si, že po otevření samotného souboru využijeme knihovnu QTextStream, které předáme parametr typu QFile. Jakmile tak provedeme, můžeme s daty velmi pohodlně zacházet. Začnou-li vás trápit problémy s diakritikou, zkontrolujte, zda máte správně nastaveno kódování.

Díky cyklu s podmínkou na začátku zajistíme obdržení samotných řádků. Ty poté ukládáme do koncové proměnné výsledek. Ještě než se tak stane, však přidáme slíbený párový tag H3. Ten navíc obohacuje vlastnost style udávající barvu písma. Metoda insertHtml pak již na závěr celé dílo sama dokoná.

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 – menu

Následující aplikace patří mezi ty jednodušší, dokáže totiž pouze sečíst dvě celá čísla. Mnohem zajímavější však je způsob ovládání. Naučíme se vytvořit klasické menu včetně toolbaru.

Práce v designérském režimu

Při zakládání nového projektu nezapomeňte, že tentokrát budeme vycházet z třídy QMainWindow. Po otevření vzhledu okna začneme s přidáním dvou prvků line edit a několika popisků (label). Kompletně vynecháme jakákoliv tlačítka a vrhneme se na ovládací nabídku. Jednoduše vypíšeme názvy jednotlivých položek v menu, které se následně usídlí ve spodní záložce Action editor. Po kliknutí na některou z nich se nám otevře okno, ve kterém lze nastavit mnoho užitečných věcí. Konkrétně si ze souboru přidáme vhodnou ikonu. Pokud žádnou nedisponujete, vyzkoušejte tzv. projekt Nuvola. Jedná se o obsáhlou sadu ikonek v nejpoužívanějších rozměrech uvolněnou pod licencí LGPL.

Qt - menu

Qt - rozbalené menu

Horké klávesy

Vždy se vyplácí aplikaci navrhovat takovým způsobem, aby ji bylo možno ovládat bez pomoci kurzoru myši. Stačí před název položky přidat znak ampersand (&) a následně lze využít následující písmeno při kombinaci s klávesou ALT pro získání kontroly nad programem. Vaši práci ocení například majitelé notebooků, kteří nemají po ruce myš a s touchpadem si příliš nerozumí.

Toolbar

Jakmile máte veškeré objekty seskupené v Action Editoru nastavené dle vašeho přání, přejděte k vytvoření toolbaru. Stačí přetáhnout libovolnou položku na požadované místo v toolbaru, který se automaticky nachází pod menu. O správném postupu vás okamžitě ubezpečí přidělená ikonka.

Zdrojový kód

Další postup již není nijak náročný. Stačí jen získat údaje z obou line editů, provést součet a výsledek nastavit jako text patřičnému labelu. Nezapomeňte rovněž propojit oba signály. Povšimněte si obzvláště slotu close(), který se postará o hladké ukončení programu. Nezapomeňte rovněž zajistit zobrazení výsledku získaného během průběhu secti() po kliknutí na Sečíst v menu.

#include „hlavniokno.h“
#include „ui_hlavniokno.h“
#include
#include

HlavniOkno::HlavniOkno(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::HlavniOkno)
{
ui->setupUi(this);
setWindowTitle(„Menu“);

QIntValidator *val;
val = new QIntValidator(this);

ui->le_prvni->setValidator(val);
ui->le_druhe->setValidator(val);

connect(ui->action_Secist,SIGNAL(triggered()),this,SLOT(secti()));
connect(ui->action_Konec,SIGNAL(triggered()),this,SLOT(close()));
}

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

void HlavniOkno::secti(){
int prvni,druhe,vysledek;
QString pom;
prvni = ui->le_prvni->text().toInt();
druhe = ui->le_druhe->text().toInt();

vysledek = prvni + druhe;

ui->l_vysledek->setText(pom.setNum(vysledek));

}

 

#ifndef HLAVNIOKNO_H
#define HLAVNIOKNO_H

#include

namespace Ui {
class HlavniOkno;
}

class HlavniOkno : public QMainWindow
{
Q_OBJECT

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

private:
Ui::HlavniOkno *ui;
public slots:
void secti();
};

#endif // HLAVNIOKNO_H