Portál AbcLinuxu, 30. dubna 2025 14:01
Když je řeč o GUI v Qt 4, nelze se nezmínit o Qt Designeru, který slouží k rychlému návrhu uživatelského rozhraní. V tomto díle se budeme zabývat relativně novým programem Qt Creator, který do sebe integruje Qt Designer, ale hlavně poslouží jako plnohodnotné IDE.
Qt Designer je nástroj pro návrh grafického rozhraní. Umožňuje vytvářet grafické rozhraní prostým přetahováním widgetů do okna. Widgetům poté můžete nastavit vlastnosti a snadno je zakomponovat do různých rozložení (layoutů) a následně dle potřeby propojit požadované signály se sloty. A to vše snadno a graficky.
Samozřejmě, že nelze vytvořit příliš smysluplnou aplikaci jen pomocí klikání a přetahování, implementaci různých akcí si stále musíte napsat sami a ke zjednodušení této činnosti je zde jiný software...
Qt Creator je relativně nové, ale již velmi schopné IDE určené pro programování za použití C++ a Qt 4. Obsahuje editor s kompletní podporou C++ (doplňování kódu, zvýraznění syntaxe a mnoho dalšího).
Jak bylo řečeno, integruje do sebe Qt Designer.
Kromě toho má i zabudovaný Qt Assistant, takže kompletní dokumentace je vždy po ruce. Tato součást je propojená s editorem tak, že stačí kurzorem myši najet na Qt objekt nebo metodu, zmáčknout F1 a relevantní dokumentace se objeví v panelu hned vedle kódu. Dále je k dispozici debugger (používá se GDB), podpora různých SCM (Git, Subversion (SVN) a Perforce) a další věci.
První program, jehož GUI navrhneme pomocí Designeru, bude celkem prostý seznam s možností přidávání, odebírání, načítání a ukládání položek.
Spustíme tedy Qt Creator, vytvoříme nový projekt (Ctrl+N) a vybereme šablonu "Qt4 Gui Application". Zvolíme název aplikace (třeba seznam) a cestu, kde se má vytvořit adresář se zdrojáky. Dále se nás Creator ptá, jaké moduly budeme v projektu používat, přičemž QtCore a QtGui jsou zaškrtnuté napevno. Zatím nebudeme potřebovat nic extra, takže přejděte dále a pojmenujte si nějak hlavní okno aplikace (výchozí název MainWindow
je ale docela příhodný). Dále je zde na výběr widget, který bude základem hlavního okna, a my z minulého dílu víme, že pro hlavní okno je obvykle vhodné použít QMainWindow. Zbytek není potřeba měnit, takže přejdeme dále a klikneme na Finish.
Vytvořil se projekt se 4 soubory. Soubor seznam.pro
je makefile pro qmake
, main.cpp
akorát spouští aplikaci (vytvoří a zobrazí hlavní widget), soubory mainwindow.h
a mainwindow.cpp
implementují hlavní okno, takže vlastně jedinou novinkou je pro nás mainwindow.ui
.
Soubory s příponou .ui
obsahují XML kód, který nese informace o navrženém widgetu, jako třeba vlastnosti (výchozí velikost, rozmístění) a propojení signálů se sloty. Takové soubory se pak při kompilaci automaticky převedou nástrojem uic
na standardní hlavičkové soubory C++. V tomto případě z mainwindow.ui
vznikne ui_mainwindow.h
, kde bude implementovaný navržený widget. My si potom v mainwindow.cpp
vytvoříme instanci tohoto widgetu a doděláme ručně, co je třeba, tzn. především prvky, které nesouvisí s GUI.
Pokud máte nainstalovaný Designer a kliknete v Creatoru na mainwindow.ui
, neotevře se vám soubor v textovém editoru, ale rovnou v zabudovaném Designeru. Uprostřed je naše nové okno, do kterého můžete z levého panelu přetahovat ovládací prvky. Přetáhněte do okna jeden seznam (List Widget), 4 tlačítka (Push Button) a jedno textové pole (Line Edit).
Teď by se hodilo tlačítka nějak uspořádat, tak je všechny postupně označíme a vložíme je do horizontálního rozložení (Ctrl+H):
Tlačítka jsou uspořádaná. Nyní označíme textové pole, nově vytvořené horizontální rozložení s tlačítky a seznam a to vše vložíme do vertikálního rozložení (Ctrl+L):
Nakonec ještě klikneme někam do prázdného místa v okně (čímž označíme MainWindow) a znova klikneme na vertikální rozložení, což způsobí to, že se všechna rozložení budou přizpůsobovat velikosti okna. Pokud jste postupovali správně, výsledkem by mělo být toto:
Dvojkliknutím na tlačítko přepíšete jeho text. Napište na tlačítka (postupně) Add, Remove, Load a Save. (To znamená Přidat, Odebrat, Načíst a Uložit.)
Pro zachování přehlednosti je docela důležité přejmenovat alespoň ty proměnné, se kterými budete pracovat ručně. To se dělá tak, že označíte objekt (v našem případě tlačítko) a v editoru vlastností, který je standardně na pravé straně, změníte "objectName". Přiřadíme tlačítkům postupně názvy addBtn, rmBtn, loadBtn, saveBtn. Dále klikněte na seznam (List Widget) a v editoru vlastností napravo si mezi vlastnostmi zděděnými ze třídy QAbstractItemView
najděte vlastnost "selectionMode" a nastavte ji na ExtendedSelection, čímž umožníte vybrat v seznamu více položek najednou. Nahoře v okně je jakýsi náznak menu a nápis "Type Here", tak tam dvojklikneme a napíšeme tam "File". Otevřeme si nově vytvořené menu "File" a dalším kliknutím na "Type Here" si v této nabídce vytvoříme položku s "Quit".
Zkusíme přiřadit položce "Quit" klávesovou zkratku. Na screenshotu výše jsem úmyslně zabral i kousek editoru akcí, ve kterém se nám před chvílí objevila položka actionQuit, na kterou nyní klikneme. Otevře se dialog, ve kterém klikneme do textového pole vedle nápisu "Shortcut" (zkratka) a následně zmáčkneme nějakou klávesovou zkratku. Vhodná je třeba Ctrl+Q.
Nakonec ještě klikneme pod menu pravým tlačítkem myši a zvolíme "Remove Tool Bar", protože panel nástrojů teď nebudeme potřebovat. Podobně můžete odstranit i Status Bar (stavový řádek). Tolik tedy ke grafickému rozhraní. Zbytek musíme ručně naprogramovat.
Než se pustíte do psaní kódu, není úplně od věci projekt sestavit, aby se vygeneroval zmiňovaný soubor ui_mainwindow.h
a fungovalo nám doplňování kódu. To uděláte snadno přes Build -> Run (Ctrl+R). Program se zkompiluje a spustí, ale nic neumí, takže ho vypneme a tento drobný nedostatek napravíme.
Základem aplikace je jako vždycky main.cpp
, ve kterém provádíme pořád to samé. Tentokrát tam vytvoříme instanci naší třídy MainWindow
.
mainwindow.h
je automaticky vygenerovaný, jen jsem do něj přidal prototypy vlastních metod.
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QSettings> // dopředná deklarace ve jmenném prostoru Ui, který // používá námi navržené rozhraní namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget* = 0); ~MainWindow(); private: Ui::MainWindow *ui; void checkSettings(QSettings&); private slots: void addItem(); void removeSelectedItems(); void loadSettings(); void saveSettings(); }; #endif // MAINWINDOW_H
mainwindow.cpp
: implementace hlavního okna.
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QDir> #include <QMessageBox> // cesta ke konfiguračnímu souboru const QString CONFIG_FILE(QDir::homePath() + "/.seznam.ini"); MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { // proměnná "ui" ukazuje na instanci grafické části našeho hlavního okna // a jsou přes ní dostupné všechny objekty, které jsme si připravili // tento příkaz načte rozhraní, které jsme si připravili ui->setupUi(this); // "Quit" zavře okno (jelikož je hlavní, tak zároveň ukončí program) connect(ui->actionQuit, SIGNAL(triggered()), this, SLOT(close())); // zavolá addItem() při stisknutí tlačítka "Add" nebo klávesy Enter connect(ui->lineEdit, SIGNAL(returnPressed()), this, SLOT(addItem())); connect(ui->addBtn, SIGNAL(clicked()), this, SLOT(addItem())); // "Remove" odstraní vybrané položky connect(ui->rmBtn, SIGNAL(clicked()), this, SLOT(removeSelectedItems())); // "Load" načte nastavení connect(ui->loadBtn, SIGNAL(clicked()), this, SLOT(loadSettings())); // "Save" uloží nastavení connect(ui->saveBtn, SIGNAL(clicked()), this, SLOT(saveSettings())); } void MainWindow::addItem() { // uložíme si text zadaný do textového pole QString text = ui->lineEdit->text(); // přidá položku s uživatelským textem (pokud byl zadán) if(!text.isEmpty()) ui->listWidget->addItem(text); // vyprázdní textové pole ui->lineEdit->clear(); // zaměření se vrátí zpět na textové pole, aby uživatel rovnou // mohl vložit další položku ui->lineEdit->setFocus(Qt::OtherFocusReason); } void MainWindow::removeSelectedItems() { // získáme seznam vybraných položek QList<QListWidgetItem*> items = ui->listWidget->selectedItems(); // a postupně je odstraníme for(int i=0; i < items.size(); ++i) delete items[i]; } // uloží položky seznamu do nastavení void MainWindow::saveSettings() { QSettings settings(CONFIG_FILE, QSettings::IniFormat); checkSettings(settings); // smaže staré nastavení settings.clear(); // postupně uloží text jednotlivých položek do konfiguračního souboru for(int i=0; i < ui->listWidget->count(); ++i) settings.setValue(QString::number(i), ui->listWidget->item(i)->text()); } // načte položky seznamu z nastavení void MainWindow::loadSettings() { QSettings settings(CONFIG_FILE, QSettings::IniFormat); checkSettings(settings); // vyprázdní seznam ui->listWidget->clear(); // postupně přidá do seznamu položky z konfiguračního souboru QStringList keys = settings.allKeys(); foreach(QString key, keys) ui->listWidget->addItem(settings.value(key).toString()); } void MainWindow::checkSettings(QSettings& settings) { // zapíšeme případné změny nastavení na disk settings.sync(); // pokud není vše bez chyb, vyskočí varovný dialog s upozorněním if(settings.status() != QSettings::NoError) QMessageBox::warning(this, tr("Settings error"), tr("Can't read the application settings!\nFile: ") + CONFIG_FILE); } MainWindow::~MainWindow() { delete ui; }
A takhle to ve výsledku vypadá:
To je pro dnešek vše. Zkuste si navrhnout své vlastní uživatelské rozhraní a implementovat mu různé funkce.
Funguje to, tak to tam asi ma co delat...Ehm... do CXXFLAGS patří optimalizace pro C++ kompilátor.
LIBS += -ltag
Zkus v QT Creatoru vlevo vybrat volbu Projects a potom se už snad doklikáš
Trošku offtopic, skúšal tu už niekto KDevelop 4? Sémantické zvýrazňovanie a doplňovanie kódu už teraz vyzerajú veľmi zaujímavo. Ak ešte k tomu započítam to, že je to KDE aplikácia so všetkými výhodami má Qt Creator oproti KDevelopu (až výjde) čo ponúknuť?
Ešte taká drobnosť ktorá mi v Qt Creatore vadí .. odsadenie tabulátorom. Dá sa nejako nastaviť aby to nepoužívalo medzery ale len tabulátor (pri písaní kódu viem nastaviť aby to použilo tabulátor, ale pri genrovaní triedy stále použije medzery.
Mimochodom som tu jediný ktorému fakt vadí vzhľad Qt Creatoru? Pri zvyšku systému, ktorý používa decentný štýl Skulpture toto vyzerá ako z inej planéty.
Ja pouzivam KDevelop4. Obcas to niekde padne, pac je v stave beta 1. Zvyraznovanie super,
podpora cmake je tez fajna. Programujem projekty v Qt, pripadne v nom robim na Krite a KDevelop4 mi dost krati cas.
Doplnovanie kodu funguje moc pekne. Doporucujem aspon skusit.
jiste jste si vsiml, ze vas nazor je nazor mensiny. Jednou budete sedet v kancelari s tou 'vetsinou' a po case budete mit strach rici otevrene svuj nazor. Klikaci zardousi jakykoliv pokrok, ale tak to ma asi byt ...
Tak, tak. Designer sice neni vsemocny, ale podstatne urychli praci. Kdyz si clovek vytvori gui z kodu, kolikrat ho strukturuje tak, aby vsechny texty na widgetech nastavoval v jedne oddelene metode, ktera se pak da volat pri kazde zmene jazyka? (aniz by se musela aplikace restartovat nebo dialog destruovat a znovu vytvorit)
Vetsinou si kazdy rekne, ze zmena jazyka kazdou hodinu je nepravdepodobna, vsechno nacpe do konstruktoru a mysli si jaky je machr, kdyz nepotrebuje designer
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.