340 likes | 548 Views
Wstęp do Qt. Qt to zestaw przenośnych bibliotek i narzędzi programistycznych dedykowanych dla języka C++ podstawowym składnikiem są klasy służące do budowy graficznego interfejsu programów komputerowych właścicielem Qt jest norweska firma Trolltech pierwsze wydanie powstało w 1995 r.
E N D
Wstęp do Qt Qt to zestaw przenośnych bibliotek i narzędzi programistycznych dedykowanych dla języka C++ podstawowym składnikiem są klasy służące do budowy graficznego interfejsu programów komputerowych właścicielem Qt jest norweska firma Trolltech pierwsze wydanie powstało w 1995 r. platformy systemowe: GNU/Linux,BSD,Solaris,UNIX,Mac OS X,MS Windows aktualna wersja oprogramowania: 4.3.3
Narzędzia programistyczne Qt • moc - specjalny preprocesor, który na podstawie plików nagłówkowych (*.h) generuje dodatkowe pliki źródłowe (*.cpp) • uic- kompilator plików *.ui zwykle generowanych za pośrednictwem programu Qt Designer • qmake - program do zarządzania procesem kompilacji; jego głównym zadaniem jest utworzenie, a później aktualizacja pliku Makefile na podstawie prostego opisu zawartego w definicji projektu (*.pro) • Qt Designer- aplikacja graficzna do definiowania graficznego interfejsu użytkownika • Qt Linguist- aplikacja wspomagająca tłumaczenie programu na różne języki • Qt Assistant- aplikacja zawierająca rozbudowany system pomocy dla programistów
Aplikacja „Hello” #include <QApplication> /* dołączenie odpowiednich bibliotek */ #include <QLabel> int main(int argc, char *argv[]) { QApplication app(argc, argv); /* utworzenie obiektu klasy QApplication, który odpowiada za działanie aplikacji */ QLabel *label = new QLabel("Hello Qt!"); /* utworzenie obiektu klasy QLabel; w konstruktorze użyto napisu, który zostanie przypisany etykiecie; możliwe jest tworzenie etykiet za pomocą języka HTML: QLabel *label = new QLabel("<h2><i>Hello</i><font color=red>Qt!</font></h2>" ) */ label->show(); /* wyświetlenie etykiety */ return app.exec(); /* przejście w stan czuwania*/ } hello.cpp
Instalacja i kompilacja Dla systemu Windows (dla języka C++): Pracę z Qt najlepiej rozpocząć od odwiedzenia strony producenta - firmy Trolltech i ściągnięcia odpowiednich narzędzi (link). Po zainstalowaniu wszystkich narzędzi konieczna jest edycja zmiennej systemowej PATH, której nowymi wartościami powinny być ścieżki do katalogu /bin z katalogu z narzędziami Qt i katalogu z zainstalowanym programem MinGW. Teraz wszystkie narzędzia potrzebne do kompilacji będą zawsze widoczne po uruchomieniu „Wiersza poleceń”. Do jednego katalogu należy skopiować wszystkie pliki programu. Następnie wykonujemy kolejno następujące instrukcje: • qmake –project • qmakenazwa_katalogu.pro • make (lub też mingw32-make) Dla systemu Linux: Po zainstalowaniu odpowiednich narzędzi wystarczy wykonać powyższe instrukcje.
Aplikacja „Quit” #include <QApplication> #include <QPushButton> int main(int argc, char *argv[]) { QApplication app(argc, argv); QPushButton *button = new QPushButton("Quit"); /* utworzenie obiektu klasu QPushButton - przycisku z etykietą „Quit” */ QObject::connect(button, SIGNAL(clicked()),&app, SLOT(quit())); /* ustawienie jednostronnego połączenia pomiędzy dwoma obiektami dwóch różnych klas; w przypadku kliknięcia w przycisk, wysyłany jest sygnał cliked(), który jest połączony z funkcją będącą slotem (quit()) */ button->show(); /* wyświetlenie przycisku */ return app.exec(); } quit.cpp
Aplikacja „Age” cz.1 #include <QApplication> #include <QHBoxLayout> #include <QSlider> #include <QSpinBox> int main(int argc, char *argv[]) { QApplication app(argc, argv); QWidget *window = new QWidget; /* obiekt służący do zarządzania oknem aplikacji */ window->setWindowTitle("Enter Your Age"); /* ustawienie etykiety okna głównego */ QSpinBox *spinBox = new QSpinBox; QSlider *slider = new QSlider(Qt::Horizontal); spinBox->setRange(0, 130); /* ustawienie zakresu */ slider->setRange(0, 130); … } age.cpp
Aplikacja „Age” cz.2 … QObject::connect(spinBox, SIGNAL(valueChanged(int)),slider, SLOT(setValue(int))); QObject::connect(slider, SIGNAL(valueChanged(int)),spinBox, SLOT(setValue(int))); /* tutaj mamy przykład ustawienia dwustronnego połączenia pomiędzy obiektami dwóch różnych klas, których praca została zsynchronizowana */ spinBox->setValue(35); QHBoxLayout *layout = newQHBoxLayout; layout->addWidget(spinBox); /* dodanie odpowiedniego widżetu do układu */ layout->addWidget(slider); window->setLayout(layout); /* powyższe cztery linie służą do zaprogramowania odpowiedniego rozmieszczenia poszczególnych elementów w oknie aplikacji */ window->show(); return app.exec(); } age.cpp
Aplikacja „Age” cz.3 Rysunek ten pokazuje zależności pomiędzy obiektem klasy QSpinBox i QSlider. Dzięki odpowiednim połączeniu zmiana wartości jednego z obiektów powoduje w konsekwencji zmianę wartości drugiego. Jest to mechanizm synchronizacji pracy dwóch widżetów.
Menadżery układu • Ułożenie widżetów w sposób przejrzysty bez naszej ingerencji jest możliwe dzięki specjalnym obiektom -menadżerom, które ustawiają rozmiar i pozycję widżetów w aplikacji. • Wyróżniamy następujące klasy takich obiektów: • - QHBoxLayout - ułożenie w poziomie (zazwyczaj od lewej do prawej) • - QVBoxLayout - ułożenie w pionie • QGridLayout – ułożenie w postaci siatki • Do „zainstalowania” odpowiedniego menadżera służy funkcja: • Qwidget::setLayout().
Asystent Qt Qt Assistant to bardzo przydatne narzędzie w poznawaniu biblioteki Qt. Zawiera bardzo obszerny opis wszystkich klas i funkcji potrzebnych do pracy.
Style Wygląd aplikacji w Qt można zmieniać dzięki użyciu różnych styli. Domyślne style są zależne od tego, w jakim systemie jest tworzona aplikacja.
Aplikacja „Find dialog” cz.1 #ifndef FINDDIALOG_H #define FINDDIALOG_H #include <QDialog> class QCheckBox;/* informacja dla kompilatora, że dane klasy istnieją */ class QLabel; class QLineEdit; class QPushButton; class FindDialog : public QDialog { Q_OBJECT /* jest to makro konieczne dla klas, w których definiowane są public: sygnały i sloty */ FindDialog(QWidget *parent = 0);/* parent - rodzic widżetu, domyślnie null */ signals: /* możliwe emitowane sygnały */ void findNext(const QString &str, Qt::CaseSensitivity cs); … finddialog.h
Aplikacja „Find dialog” cz.2 … void findPrevious(const QString &str, Qt::CaseSensitivity cs); /* Qt::CaseSensivity to typ wyliczeniowy, który przyjmuje dwie wartości: Qt::CaseSensitive lub Qt::CaseInsensitive */ private slots: /* słowo kluczowe slots jest to makro dla kompilatora C++ */ void findClicked(); void enableFindButton(const QString &text); private: QLabel *label; QLineEdit *lineEdit; QCheckBox *caseCheckBox; QCheckBox *backwardCheckBox; QPushButton *findButton; QPushButton *closeButton; }; #endif finddialog.h
Aplikacja „Find dialog” cz.3 #include <QtGui> /* plik zawierający definicję klas GUI */ #include "finddialog.h" FindDialog::FindDialog(QWidget *parent): QDialog(parent) { label = new QLabel(tr("Find &what:")); /* tr() - oznaczenie napisu do translacji */ lineEdit = new QLineEdit; label->setBuddy(lineEdit); /* buddy - widżet akceptujący podświetlenie przy wciśnięciu klawiszu skrótu */ caseCheckBox = new QCheckBox(tr("Match &case")); /* & - oznaczenie skrótu */ backwardCheckBox = new QCheckBox(tr("Search &backward")); findButton = new QPushButton(tr("&Find")); findButton->setDefault(true); /* wartość domyślna */ findButton->setEnabled(false); /* dostępność */ closeButton = new QPushButton(tr("Close")); … finddialog.cpp
Aplikacja „Find dialog” cz.4 … connect(lineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(enableFindButton(const QString &))); /* przycisk staje się dostępny jeżeli pojawi się sygnał o wpisaniu tekstu */ connect(findButton, SIGNAL(clicked()), this, SLOT(findClicked())); /* wywołanie findClicked() po kliknięciu */ connect(closeButton, SIGNAL(clicked()),this, SLOT(close())); QHBoxLayout *topLeftLayout = new QHBoxLayout; topLeftLayout->addWidget(label); /* dodawanie widżetu */ topLeftLayout->addWidget(lineEdit); QVBoxLayout *leftLayout = new QVBoxLayout; /* tworzenie obiektu menadżera */ leftLayout->addLayout(topLeftLayout); leftLayout->addWidget(caseCheckBox); leftLayout->addWidget(backwardCheckBox); … /* dzięki zagnieżdżeniu wszystkich rodzajów menadżerów możliwe jest dowolne ułożenie wszystkich widżetów w przjrzystej i czytelnej formie */ finddialog.cpp
Aplikacja „Find dialog” cz.5 … QVBoxLayout *rightLayout = new QVBoxLayout; rightLayout->addWidget(findButton); rightLayout->addWidget(closeButton); rightLayout->addStretch(); QHBoxLayout *mainLayout = new QHBoxLayout; mainLayout->addLayout(leftLayout); mainLayout->addLayout(rightLayout); setLayout(mainLayout); /* ustawienie układu głównego */ setWindowTitle(tr("Find")); /* etykieta dla okna głównego aplikacji */ setFixedHeight(sizeHint().height());/* QWidget::sizeHint() zwraca idealny rozmiar */ } finddialog.cpp
Aplikacja „Find dialog” cz.6 void FindDialog::findClicked() { /* slot findClicked() jest wywoływany jeżeli QString text = lineEdit->text(); wciśnięty zostanie przycisk wyszukiwania */ Qt::CaseSensitivity cs = caseCheckBox->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive; if (backwardCheckBox->isChecked()) emit findPrevious(text, cs); /* sprawdzanie czy zaznaczono wyszukiwanie do tyłu */ else emit findNext(text, cs); } void FindDialog::enableFindButton(const QString &text) { findButton->setEnabled(!text.isEmpty()); /* ustawianie dostępności przycisku */ } /* Kompilacja programu odbywa się w sposób opisany wcześniej. W związku z tym, że klasa FindDialog zawiera makro Q_OBJECT plik wykonywalny generowany przez qmake zawiera specjalne zasady dla uruchomienia moc - meta - object compiler */ finddialog.cpp
Sygnały i sloty Jest to fundamentalny mechanizm w programowaniu przy użyciu bibliotek Qt. Umożliwia on programiście łączenie obiektów w sytuacji gdy obiekty „nie znają się”. Sloty są jak zwykłe funkcje w C++. Mogą być wirtualne, przeładowane, publiczne, chronione czy też prywatne. Ich parametry mogą być różnych typów. Różnica jest taka że sloty mogą być połączone z sygnałami co oznacza że są automatycznie wywoływane jeżeli sygnał zostanie wyemitowany. Składnia funkcji connect(): connect(sender, SIGNAL(signal), receiver, SLOT(slot)) Możliwe jest łączenie jednego sygnału do wielu slotów, wielu sygnałów do tego samego slotu, sygnału z sygnałem. Dane połączone można usunąć poprzez funkcję disconnect. Jeżeli chcemy połączyć sygnał ze slotem lub z innym sygnałem obydwa muszą mieć parametry tego samego typu, zapisane w tej samej kolejności. Jeżeli parametry są w złej kolejności lub jeśli sygnał lub slot nie istnieje pojawi się ostrzeżenie.
Meta - Object System Ważnym osiągnięciem było rozszerzenie Qt o język C++ z mechanizmem dla tworzenia niezależnego oprogramowania komponentowego. Mechanizm ten to meta - object system, który świadczy dwie kluczowe usługi: • połączenie sygnał - slot • introspekcja -funkcjonalność introspekcji jest potrzebna przy implementacji sygnałów i slotów i pozwala uzyskać dostęp do meta - informacji o podklasach klasy QObject podczas uruchomienia; mechanizm ten wspiera również właściwości obiektów (dla Qt Designer`a) a także translację tekstów Standard C++ nie dostarcza wsparcia dla meta - informacji potrzebnych dla meta – object system. Qt rozwiązuje ten problem poprzez moc, który analizuje definicje klasy Q_OBJECT i czyni te informacje dostępnymi poprzez funkcje z języka C++. Działanie mechanizmu: • makro Q_OBJECT deklaruje kilka podstawowych funkcji • narzędzie moc generuje implementację dla funkcji zadeklarowanych przez Q_OBJECT i dla wszystkich sygnałów i slotów • funkcje klasy QObject takie jak connect() czy disconnect() używają tych funkcji
Qt designer Qt designer jest bardzo przydatnym narzędziem w tworzeniu aplikacji wykorzystujących bibliotekę Qt. Aplikacja ta służy do definiowania graficznego interfejsu użytkownika (może być używana do całkowitego lub częściowego jej tworzenia). Zaletą jest możliwość eksperymentowania z różnymi elementami bez konieczności ręcznego kodowania zmian.
Aplikacja „Go to cell” cz.1 Do utworzenia graficznego interfejsu użytkownika używamy programu Qt designer. Po utworzeniu formy i zapisaniu jej do pliku z rozszerzeniem *.ui należy stworzyć program główny dla aplikacji. #include <QApplication> #include <QDialog> #include "ui_gotocelldialog.h" /* jest to plik generowany, przez uic – user – interface int main(int argc, char *argv[]) compiler – kompilator interfejsu użytkownika, na { podstawie pliku *.ui do języka C++ */ QApplication app(argc, argv); Ui::GoToCellDialog ui;/* obiekt reprezentujący interfejs użytkownika */ QDialog *dialog = new QDialog; ui.setupUi(dialog); /* inicjalizacja formy */ dialog->show(); return app.exec(); } gotocell.cpp
Aplikacja „Go to cell” cz.2 Aplikacja stworzona przy użyciu Qt designer`a właściwie nie robi nic. Teraz musimy zaprogramować odpowiedni dialog z użytkownikiem. #ifndef GOTOCELLDIALOG_H #define GOTOCELLDIALOG_H #include <QDialog> #include "ui_gotocelldialog.h„ class GoToCellDialog : public QDialog, public Ui::GoToCellDialog { Q_OBJECT /* makro Q_OBJECT */ public: GoToCellDialog(QWidget *parent = 0); private slots: void on_lineEdit_textChanged(); }; #endif gotocelldialog.h
Aplikacja „Go to cell” cz.3 #include <QtGui> #include "gotocelldialog.h" GoToCellDialog::GoToCellDialog(QWidget *parent): QDialog(parent) { setupUi(this); /* inicjalizacja formy */ QRegExp regExp("[A-Za-z][1-9][0-9]{0,2}"); /* akceptowalne wyrażenia regularne */ lineEdit->setValidator(new QRegExpValidator(regExp, this)); connect(okButton, SIGNAL(clicked()), this, SLOT(accept())); connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject())); connect(lineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(on_lineEdit_textChanged())); /* ustanowienie połączeń; dla przycisku okButton - accept(), cancelButton - reject(); ostatnie połączenie służy do ustawienia dostępności przycisku okButton jeżeli wprowadzony tekst jest poprawny */ } void GoToCellDialog::on_lineEdit_textChanged() /* sprawdzanie czy podane wyrażenie { jest poprawne */ okButton->setEnabled(lineEdit->hasAcceptableInput()); } gotocelldialog.cpp
Rozszerzanie okien dialogowych cz.1 Dzięki Qt przy użyciu różnych wbudowanych mechanizmów możliwe jest tworzenie okien dialogowych przyjmujących różne kształty. #include <QtGui> #include "sortdialog.h" SortDialog::SortDialog(QWidget *parent): QDialog(parent) { setupUi(this); secondaryGroupBox->hide(); /* w konstruktorze część „secondary i tertiary” jest tertiaryGroupBox->hide(); ukrywana */ layout()->setSizeConstraint(QLayout::SetFixedSize); /* za rozmiar okna dialogowego od tego momentu odpowiada menadżer układu okna */ setColumnRange('A', 'Z'); /* ustawienie zakresu dla nazw kolumn */ } … sortdialog.cpp
Rozszerzanie okien dialogowych cz.2 … void SortDialog::setColumnRange(QChar first, QChar last) { primaryColumnCombo->clear(); /* wyczyszczenie ColumnBox - ów */ secondaryColumnCombo->clear(); tertiaryColumnCombo->clear(); secondaryColumnCombo->addItem(tr("None")); /* dodanie elementu „None” */ tertiaryColumnCombo->addItem(tr("None")); primaryColumnCombo->setMinimumSize(secondaryColumnCombo->sizeHint()); QChar ch = first; /* powyżej dodanie idealnego rozmiaru dla widżetu */ while (ch <= last) { primaryColumnCombo->addItem(QString(ch)); /* dodanie elementów określających secondaryColumnCombo->addItem(QString(ch)); nazwy kolumn */ tertiaryColumnCombo->addItem(QString(ch)); ch = ch.unicode() + 1; } /* w aplikacji głównej dodatkowo ustawiamy zakres nazw dla kolumn wywołując }funkcję setColumn Range */ sortdialog.cpp
Rozszerzanie okien dialogowych cz.3 • Qt designer dostarcza również inne obiekty przydatne w tworzeniu aplikacji, w których okna dialogowe mogą być w różny sposób rozszerzane. • Prostym sposobem kontrolowania rozszerzeń jest np. tworzenie specjalnych etykiet na przyciskach, które łatwo zmienić za pomocą funkcji setText(), w zależności od tego w jakiej pozycji znajduje się okno dialogowe. • Przykłady klas obiektów: • QTabWidget – pozwala na tworzenie widżetów pełniących • rolę zakładek • QStackWidget i QListWidget – obiekty tych klas mogą • być jednocześnie użyte, gdzie aktualna pozycja obiektu • klasy QListWidget określa, którą stronę ma wyświetlić • widżet będący obiektem klasy QStackWidget poprzez • odpowiednie połączenie tych obiektów za pomocą • sygnałów i slotów • QStackWidget i QTreeWidget – podobne zastosowanie jak • w powyższym przykładzie
Rozszerzanie okien dialogowych cz.4 Dynamiczne okna dialogowe są tworzone na podstawie plików z rozszerzeniem *.ui. Zamiast konwertować pliki *.ui do kodów źródłowych języka C++ możemy załadować te pliki bezpośrednio w trakcie uruchomienia programu za pomocą obiektów klasy QUiLoader. QUiLoader uiLoader; QFile file("sortdialog.ui"); QWidget *sortDialog = uiLoader.load(&file); if (sortDialog) { ... } QComboBox *primaryColumnCombo = /* użycie wzorca funkcji */ sortDialog->findChild<QComboBox *>("primaryColumnCombo"); if (primaryColumnCombo) { ... /* powyższy przykład pokazuje w jaki sposób możemy znaleźć obiekty - } widżety pochodne na podstawie zgodności nazwy i typu */ Aby możliwe było użycie obiektu klasy QUiLoader w naszej aplikacji należy dodać poniższą linię do pliku *.pro: CONFIG += uitools
Wbudowane widżety cz.1 • różnego rodzaju przyciski: • QPushButton i QToolButton: służą do zainicjowania określonej akcji w przypadku kliknięcia • QCheckBox: przydatne do zaznaczania że coś jest włączone lub też nie • QRadioButton: wybór jednej z dostępnych opcji • tzw. kontenery: są to widżety, które zawierają w sobie inne widżety
Wbudowane widżety cz.2 • widżety, które służą do rozszerzania okien dialogowych - zawierają podstrony, które są potomkami widżetu głównego i które są numerowane • widżety, które służą do obsługi dużej ilości danych
Wbudowane widżety cz.3 • Qt zawiera również kilka prostych widżetów, które służą wyłącznie do wyświetlania informacji: • QLabel - jest najważniejszy ze wszystkich widżetów tego typu; może być użyty do wyświetlania zwykłego tekstu a także obrazków (użycie HTML) • QTextBrowser - bazuje na kodzie HTML (obsługa tabel, obrazków, list itp.) • QProgressBar - ukazanie postępu
Wbudowane widżety cz.4 • widżety, które służą do wprowadzania różnego rodzaju danych i informacji • QLineEdit - jest podstawowym widżetem z tej kategorii • QTextEdit - edytowanie większych ilości tekstu • QDataEdit,QTimeEdit,QDateTimeEdit - widżety związane z czasem • QScrollBar, QSlider,QDial - użycie specjalnego suwaka
Wbudowane widżety cz.5 • widżety umożliwiające wybór czcionki czy też koloru • widżety umożliwiające obsługę plików, funkcję drukowania, ustawiania strony
Wbudowane widżety cz.6 • widżety specjalne, która służą do informowania użytkownika o pewnych zainstniałych sytuacjach, zachęcające do wykonania jakiejś akcji • QProgressDialog - ukazanie postępu • QinputDialog - zachęcenie użytkownika do podania jakiejś informacji • QMessageBox, QErrorMessage - informujące użytkownika o jakiejś sytuacji
Bibliografia • http://www.pl.wikipedia.org/wiki/Qt • http://www.trolltech.com/products/qt • http://www.binboy.sphere.pl/index.php?show=serwis&d=qtportal • http://www.free.of.pl/q/qtmoux/ • http://www.jtz.org.pl/Inne/QT-Tutorial/tutorial.html • http://www.books.google.pl • AUTOR: • EMIL KRAWCZYŃSKI • SEMINARIUM, III ROK INFORMATYKI UMCS