Moje zdjęcie
Uczeń LO im. Ma­­ła­chow­skie­go w Płoc­ku. Lubi czy­tać książ­ki. Ma du­żo po­my­słów, jed­nak za­zwy­czaj ma­ło chę­ci lub nie­do­bór umie­jęt­no­ści na ich re­ali­za­cję. In­te­re­su­je się pro­gra­mo­wa­niem. Bie­rze udział w kon­kur­sie po to aby na­uczyć się cze­goś no­we­go. Ocze­ku­je na kon­struk­tyw­ną kry­ty­kę.

niedziela, 3 października 2010

200: Zaczynamy zabawę z Qt

Co prawda baza danych nie jest jeszcze skończona, jednak przyznam szczerze - skupienie się wyłącznie na niej było błędem. Praca nad nią była nudna i dlatego prace szły bardzo wolno. Za to bardzo lubię projektować interfejsy (chociaż specjalistą nie jestem). Dlatego ostatia faza tworzenia systemu bazy danych będzie przeprowadzana równolegle z tworzeniem podstaw GUI.

Logtree jest z założenia projektem dość nietypowym, GUI także będzie odmienne od tego co widoczne jest w innych programach do notatek czy pamiętników. Mam nadzieję, że uda się spełnić wszystkie założenia, jakie sobie postawiłem.

Po tym przydługim wstępie czas przejść do rzeczy, czyli pracy z Qt. Nie będę się rozpisywał na temat historii biblioteki, bo nie ma to najmniejszego sensu - nie jest przydatna przy programowaniu, a jak ktoś chce ją znać, to można wygooglować w 15 sekund. Zatem, zaczynamy!

Samo tworzenie nowego projektu nie jest zbytnio porywające. Na ekranie powitalnym klikamy Utwórz projekt..., czym włączamy kreator, w którym wybieramy typ projektu (Aplikacja GUI Qt), lokalizację źródeł czy szczegóły klasy odpowiadającej za okno. Jedyna naprawdę istotna dla mnie rzecz w tym kreatorze to możliwość wyłączenia generowania formularza Qt Designer, z którego i tak nie będę korzystał. Dlaczego?

Cóż, według mnie korzystanie z Qt Designera jest dobre do tworzenia prostych, statycznych interfejsów. Obecnie ten wbudowany w Qt Creatora nie umożliwia nawet używania własnych widgetów. Jest to bardzo istotny problem, gdyż każda zmiana funkcjonalności kontrolki oznacza stworzenie jej potomka, czyli zupełnie nowego widgetu. Próba zrobienia tego graficznie oznacza stworzenie osobnego projektu dla elementu graficznego, kompilację jako pluginu do Qt Designera (ale nie tego wbudowanego), stworzenie formularza, kompilację szablonu i dopiero kompilację projektu. Dla każdej, nawet najmniejszej, zmiany w widgecie, której nie obejmują właściwości klasy. Dlatego właśnie interfejs Logtree będzie generowany dynamicznie i zapisany w kodzie projektu.

Zatem stworzyliśmy już nowy projekt aplikacji GUI Qt bez formularza. Co otrzymaliśmy? Trzy pliki. Pierwszy z nich - main.cpp, którego prawdopodobnie nigdy nie będziemy edytować. Tworzy obiekt QApplication, który odpowiada za działanie aplikacji, oraz MainWindow, która to klasa dziedziczy po QMainWindow i zarządza oknem głównym programu.

#include <QtGui/QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

Pozostałe dwa - mainwindow.h i mainwindow.cpp, odpowiadają za wspomnianą wyżej klasę MainWindow, która w tym momencie składa się tylko z konstruktora, który dziedziczy po konstruktorze klasy QMainWindow i nie robi nic poza tym, oraz destruktora, który już w ogóle nic nie robi. Wygląda to tak:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGui/QMainWindow>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
};

#endif // MAINWINDOW_H

Tutaj warto zwrócić uwagę na linię 8, czyli makro Q_OBJECT, które jest niezbędne, jeżeli chcemy używać systemu sygnałów i slotów (o którym szerzej można przeczytać w internecie, ewentualnie można poczekać aż ja o nim napiszę, a zrobię to wkrótce), czyli właściwie pozbawić klasę możliwości jakiejkolwiek interakcji z otoczeniem. Reszta jest mało interesująca.

Bardziej pasjonujący jest drugi plik. Co prawda nie w wersji surowej, której nawet nie będę przytaczać. Na wstępie przydałoby się jednak dodać do niego 4 linijki, z czego przynajmniej jedna wymaga komentarza.

#include <QTextCodec>
#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Windows-1250"));
    this->setGeometry(100, 100, 800, 600);
    this->setWindowTitle("Logtree");
}

MainWindow::~MainWindow()
{

}

Dość oczywiste są linie 8 i 9. Krótko: pierwsza z nich ustawia lewy górny róg okna 100 pikseli na prawo i w dół od lewego górnego rogu ekranu, a wymiary okna na 800px szerokości i 600px wysokości. Następna linia ustawia tytuł okna na Logtree. Natomiast linia numer 7 ustawia kodowanie znaków, co wymaga pliku dołączanego w pierwszej linijce. W większości kursów i tutoriali umieszcza się ten kod nie w konstruktorze klasy MainWindow, a w funkcji main. Dlaczego zdecydowałem się na inne wyjście? Z racji zrezygnowania z Qt Designera będę miał utrudnione zadanie jeżeli chodzi o lokalizację. System tłumaczeń Qt zmienia kodowanie automatycznie w zależności od lokalizacji, w obecnym rozwiązaniu jestem tego pozbawiony i muszę robić to ręcznie. Wiąże się to z ponownym uruchomieniem aplikacji przy każdej zmianie tłumaczenia. Zatem ustawianie stałego kodowania przy starcie aplikacji jest nieco niefortunne, więc linia ta pojawia się tu tylko tymczasowo - do czasu implementacji systemu tłumaczeń. Później zostanie usunięta. Ktoś mógłby spytać: zatem co to za różnica, gdzie ją umieścisz? To proste - do main.cpp nikt nie zagląda ;) Zapomnę, zostawię, a potem będę się dziwił, że kodowanie zostaje bez zmian.

Projekt w Qt Creatorze stworzony, można go skompilować i uruchomić, by zobaczyć okno wielkości 800x600, 100 pikseli w dół i w prawo od górnego lewego rogu ekranu, mające tytuł Logtree... i nic poza tym. A w następnym poście za 15 minut - usuniemy ten szary prostokąt!

Brak komentarzy:

Prześlij komentarz