2006.02_Qt ISO Maker–moja pierwsza aplikacja w Qt_[Programowanie].pdf

(840 KB) Pobierz
439111984 UNPDF
programowanie
Qt ISO Maker
– moja pierwsza
aplikacja w Qt
Tomasz Pielech
programowanie aplikacji
okienkowych w Linuksie
jest proste. Ten artykuł
udowodni tę tezę; wykonamy pierwszą
aplikację, która będzie służyła do two-
rzenia obrazów płyt CD. Program będzie
umożliwiał przeglądanie plików i katalo-
gów znajdujących się na dysku i dodawa-
nie ich do obrazu. Sam proces tworzenia
będzie opierał się na programie Mkisofs ,
więc w rzeczywistości stworzymy graicz-
ną nakładkę na ten program.
ce m.in. do generowania plików Makeile )
mogły zostać znalezione. Tę część powin-
ny wykonać za nas skrypty dołączone do
pakietów z biblioteką. W niektórych przy-
padkach (np. gdy wydanie polecenia qmake
zwróci błąd “command not found” ) może
okazać się konieczne utworzenie zmiennej
systemowej QTDIR , która będzie zawie-
rała ścieżkę do katalogu z biblioteką Qt.
Przykładowo, jeśli Qt jest zainstalowane
w katalogu /usr/lib/qt3 , to w pliku ~/.bashrc
powinniśmy dopisać:
export QTDIR=/usr/lib/qt3
Narzędzia, wymagania
systemowe
Omawiana tutaj aplikacja zostanie wyko-
nana przy pomocy biblioteki Qt i narzę-
dzi dostarczonych razem z nią. W trak-
cie przygotowania artykułu korzystałem
z biblioteki Qt w wersji 3.3.3 oraz kompi-
latora GCC 3.3.5. Aby uniknąć podstawo-
wych błędów związanych z kompilacją
źródeł, wymagane jest posiadanie biblio-
teki Qt w wersji 3.3 lub wyższej. Wersja
kompilatora nie ma większego znaczenia.
Programy tworzone z użyciem Qt można
kompilować zarówno w GCC3, GCC4, jak
również korzystając z innych kompilato-
rów, np. Intela.
W systemach, w których oprogramo-
wanie jest dystrybuowane w postaci
RPM-ów, powinniśmy posiadać następuj-
ące pakiety ( Aurox ): qt-designer , qt-3.3.3
oraz qt-devel . W systemach, w których
oprogramowanie jest dystrybuowane w po-
staci DEB-ów, powinniśmy posiadać na-
stępujące pakiety ( Ubuntu ): qt3-apps-dev ,
qt3-assistant , qt3-designer , qt3-dev-tools oraz
qt3-doc .
Komplenta koniguracja tych narzędzi
powinna zapewniać, aby pliki bibliotek
oraz pliki i programy używane w procesie
kompilacji (np. Qmake – narzędzie służą-
Na CD/DVD
Na CD/DVD znajduje się kod
źródłowy tworzonej aplikacji.
Rozpoczęcie pracy
– projekt aplikacji
Pierwszym elementem przy tworzeniu
naszej aplikacji będzie stworzenie okien-
ka, w którym będą rozmieszczone wszyst-
kie kontrolki używane przez program.
Do jego stworzenia wykorzystamy pro-
gram Qt Designer , który ułatwi nam stwo-
rzenie całego interfejsu. Za jego pomocą
stworzymy również projekt aplikacji (plik
o rozszerzeniu pro ), a także plik main.cpp .
Ważne jest więc, aby prześledzić uważnie
wszystkie opisywane poniżej kroki, gdyż
pozwoli nam to uniknąć wielu niepotrzeb-
nych błędów.
W pierwszym kroku stworzymy plik
projektu naszej aplikacji. W tym celu uru-
chamiamy program Qt Designer i w okien-
ku Qt Designer New/Open (lub po wybraniu
File->New ) wskazujemy opcję C++ Project .
Plik ten zapisujemy w katalogu specjalnie
przygotowanym do tego celu. W omawia-
nym przykładzie będzie to ~/Projekty/qtiso/ ,
a nazwa pliku to qtiso.pro .
Rysunek 1 przedstawia ekran Qt De-
signera. Oznaczenia to w kolejności: (1)
Przestrzeń robocza, w której będą poja-
wiać się okienka; (2) Elementy graicznego
interfejsu aplikacji; (3) Właściwości aktual-
24 luty 2006
W brew obiegowym opiniom,
439111984.047.png 439111984.054.png 439111984.055.png
 
439111984.001.png 439111984.002.png 439111984.003.png 439111984.004.png 439111984.005.png 439111984.006.png 439111984.007.png
 
programowanie w Qt
programowanie
nie zaznaczonego elementu; (4) Elementy
klasy, które są tworzone na podstawie
okna; (5) Przyciski umożliwiające roz-
mieszczanie elementów interfejsu.
Po zapisaniu pliku projektu przy-
stępujemy do etapu właściwego, czyli
tworzenia okienka naszego programu.
W menu File->New wybieramy Main Win-
dow . Kreator, który pojawi się, możemy
od razu zamknąć przyciskiem Cancel .
Teraz nazwiemy nasze okienko. W prawej
części programu Qt Designer powin-
na być zakładka Properties (punkt 3 na
Rysunku 1) ze wszystkimi właściwościa-
mi. Odszukujemy na tej liście wartość name
i wpisujemy tam qtISOMForm . Po wpisa-
niu tej nazwy zapisujemy plik okna, na
którym za chwilę będziemy umieszczać
kolejne elementy interfejsu.
Ostatnim krokiem w przygotowy-
waniu projektu naszej pierwszej aplika-
cji będzie stworzenie pliku main.cpp . W
tym celu ponownie wybieramy z menu
File->New , a następnie C++ Main-File .
Po wybraniu tego pliku będziemy mogli
wybrać główne okno programu. Jeśli
wszystkie kroki przeprowadziliśmy pra-
widłowo, to na liście będziemy mieli tylko
jedną pozycję, więc wystarczy po prostu
zatwierdzić przyciskiem OK . Po wygene-
rowaniu pliku main.cpp możemy go zapi-
sać i od razu zamknąć, gdyż nie będzie-
my modyikować jego treści. Jedynym jego
zadaniem jest uruchomienie głównej pętli
naszej aplikacji (w tym przypadku chodzi
o pętlę w rozumieniu sygnałów i slotów,
gdyż jej działanie polega na tym, że aplika-
cja działa tak długo, aż nie zostanie wyge-
nerowany sygnał lastWindowClosed() ;
dopiero wówczas następuje zamknięcie
aplikacji i usunięcie jej z pamięci), która
wyświetli okno qtISOMForm .
Listing 1. Kod wczytujący listę katalogów systemu do kontroli ListView
#include <qdir.h>
void qtISOMForm :: init () {
listDir -> setRootIsDecorated ( true );
mainDirRead ();
}
void qtISOMForm :: mainDirRead () {
QDir dir ( "/" );
dir . setFilter ( QDir :: All );
QStringList content = dir . entryList ();
QListViewItem * newItem ;
for ( QStringList :: Iterator it = content . begin ();
S
it != content . end (); ++ it ) {
if (( QString :: compare (* it , ".." ) != 0 )
S
&& ( QString :: compare (* it , "." ) != 0 )) {
QFileInfo ileinfo ( "/" + * it );
newItem = new QListViewItem ( listDir , * it );
if ( ileinfo . isReadable () && ileinfo . isDir ())
newItem -> setPixmap ( 0 , QPixmap ( "images/dir.png" ));
if (! ileinfo . isReadable () && ileinfo . isDir ())
newItem -> setPixmap ( 0 , QPixmap ( "images/dirro.png" ));
if ( ileinfo . isFile ())
newItem -> setPixmap ( 0 , QPixmap ( "images/ile.png" ));
}
}
}
proces wymagający, po pierwsze, umiesz-
czenia wszystkich kontrolek wykorzy-
stywanych przez program, a po drugie,
poprawnego ich rozmieszczenia.
Na początku dodamy menu do nasze-
go okienka. Wykonujemy to poprzez
kliknięcie prawym klawiszem myszy w
dowolnym miejscu głównego formularza,
a następnie wybraniu opcji Add Menu item .
Po wykonaniu tej operacji będzie od razu
widoczne menu, które możemy dosto-
sować do swoich potrzeb. Utworzymy
teraz dwie pozycje: File i Help . Do menu
File dodamy dwa elementy: Save ISO oraz
Exit , a w menu Help dodamy tylko pozy-
cję About .
Wykonanie tych czynności jest stosun-
kowo intuicyjne. Podam kilka użytecz-
nych porad, które mogę przydać się pod-
czas tworzenia menu. Po pierwsze, gdy
klikamy myszą na jakimś menu, możemy
wykorzystać klawisz [ F2 ], aby zmienić
jego nazwę. Po drugie, użycie klawisza
[ F2 ], gdy jest zaznaczona pozycja new item ,
wpisanie nowej nazwy menu i zatwier-
dzenie klawiszem [ Enter ] powoduje doda-
nie nowej pozycji. Po trzecie, użycie znaku
ampersand “&” przed literą, w nazwie
którejś z menu, umożliwia uruchomie-
nie tej opcji za pomocą skrótu klawiaturo-
wego. Przykładowo, jeśli przed literą “ F
podamy znak &, to w programie po skom-
pilowaniu użycie klawiszy [ Alt ]+[ F ] spo-
woduje rozwinięcie menu File . Dodanie
separatora (pionowa linia oddzielająca
pozycje w menu) do menu jest możliwe
po przeciągnięciu go metodą przeciągnij
i upuść w odpowiednie miejsce.
Gdy dodamy wszystkie trzy wymie-
nione wcześniej elementy do menu, będą
one widoczne w oknie Action Editor .
Dodamy teraz elementy interfejsu do
obsługi systemu plików. Będzie to ListView
dostępne z menu Tools->Views->ListView .
Dokonamy teraz edycji tej kontrolki. Aby
było to możliwe, klikamy na nią dwu-
krotnie. Powinno ukazać się nam okien-
ko Edit ListView z aktywną zakładką Items .
Usuniemy domyślnie dodaną pozycję New
Item oraz w zakładce Columns zmienimy
nazwę kolumny na Directories . W oknie
Properties zmienimy nazwę obiektu (kon-
trolki listView1 ) na listDir . Dodamy
teraz jeszcze kontrolkę Display->TextLabel
oraz Buttons->PushButton . Pierwszą umie-
ścimy ponad listDir , a drugą poniżej. Treść
wyświetlaną przez textLabel możemy zmie-
nić klikając dwukrotnie na tym elemencie.
Wpiszemy tutaj: List of iles and directories.
Zmianę tekstu na przycisku wykonuje-
Tworzenie GUI
Przygotowanie GUI programu z wyko-
rzystaniem Qt Designera jest stosunkowo
proste. Należy jednak pamiętać, że jest to
Rysunek 1. Ekran Qt Designera
www.lpmagazine.org
25
439111984.008.png 439111984.009.png 439111984.010.png 439111984.011.png 439111984.012.png 439111984.013.png 439111984.014.png 439111984.015.png 439111984.016.png 439111984.017.png
programowanie
Rysunek 2. Wykonanie GUI
czenie tych kontrolek tak, aby w każdej roz-
dzielczości ekranu oraz niezależnie od usta-
wień personalnych użytkownika bądź sys-
temu (takich jak np. wykorzystywane style)
były poprawnie wyświetlane. Zaznaczamy
wszystkie kontrolki, a mówiąc dokładniej,
dwie grupy kontrolek i wybieramy opcję
Layout->Lay Out Horizontally (in Splitter) ,
a następnie klikamy w dowolnym miejscu
na formularzu okna (tak, aby nic nie było
zaznaczone) i wybieramy opcję Layout->Lay
Out in a Grid .
Ostatnim krokiem, który nam jesz-
cze pozostał w przygotowaniu GUI
naszej aplikacji, jest zmiana tytułu, który
jest wyświetlany przez główne okno. Na
zakładce properties odszukujemy pozycję
caption i wpisujemy: Qt ISO Maker . Jeśli
wszystkie kroki wykonaliśmy zgodnie z
tym, co zostało opisane, to powinniśmy
ujrzeć surowy projekt aplikacji podobny
do tego zaprezentowanego na Rysunku 2.
O tworzeniu GUI Czytelnik powinien
pamiętać, że samo umieszczenie kontrolek
na formularzu nie jest jeszcze wystarcza-
jące, jak również, że poprawne rozmiesz-
czenia jest niezwykle istotne, gdy aplikacja
ma być dostępna dla osób korzystających z
innych środowisk graicznych lub dystry-
bucji. Postępowanie z menedżerami roz-
mieszczania (na Rysunku 2 widoczne są
w postaci czerwonych linii) jest analogicz-
ne do projektowania stron internetowych
i stosowania znacznika table . Layouty
są swego rodzaju tabelkami, do których
będą justowane kontrolki. Zarówno przy
projektowaniu stron internetowych, jak
i w przypadku programowania z użyciem
Qt, prawidłowe wykonanie pozycjonowa-
nia poszczególnych elementów jest szcze-
gólnie ważne, gdy strona bądź program
będzie wykorzystywany na innych kom-
puterach niż ten, na którym został stwo-
rzony i wygląda ładnie.
Kod aplikacji
Środowisko Qt Designer (w Qt z serii 3.x)
umożliwia nam, oprócz tworzenia GUI
aplikacji, również tworzenie kodu progra-
mu. Zanim przejdziemy do samego two-
rzenia kodu, omówię jeszcze udogodnie-
nia, które oferuje nam Qt Designer. Warto
jednak zaznaczyć, że cały kod, który
będziemy tworzyć, nie jest kompletnym
kodem, z jakiego będzie zbudowany pro-
gram. Na podstawie tego kodu, jak rów-
nież pewnych zmiennych, które zostaną
teraz omówione, będzie generowany wła-
ściwy kod programu (pliki *.h i *.cpp ).
my w analogiczny sposób. Tu wpiszemy
A&dd . Zmienimy jeszcze nazwę przycisku
( Properties->name ) na addBtn .
Gdy wszystkie te operacje będziemy
mieli za sobą, wykonamy bardzo istotną
czynność, jaką jest grupowanie kontrolek.
W tym celu musimy zaznaczyć wszyst-
kie trzy kontrolki (zaznaczanie wykonu-
je się analogicznie do zaznaczania ikon
np. na pulpicie). Gdy będą zaznaczone,
wybieramy opcję Lay Out Verticaly (przy-
cisk z trzema poziomymi liniami na pasku
narzędziowym Qt Designera) lub używa-
my kombinacji klawiszy [ Ctrl ]+[ L ]. Od tej
pory wszystkie trzy kontrolki mogą być
traktowane jako jedna podczas dalszego
rozmieszczenia.
Gdy już wiemy, jak dodawać i rozmiesz-
czać kontrolki na formatkach Qt Designera,
dodamy jeszcze trzy. Będą to textLabel , list-
Box , pushButton . Tekst w kontrolce textLabel
zmienimy na Add this to ISO . Z listBox
usuniemy domyślnie dodaną pozycję ( New
item ) i zmienimy jej nazwę na listIso . Na
przycisku napiszemy Re&move , a następnie
zgrupujemy wszystkie trzy tak samo jak w
poprzednim akapicie.
W chwili obecnej mamy już wszystkie
kontrolki niezbędne do wykonania pod-
stawowej funkcjonalności naszej aplikacji.
Niezbędne jest jednak poprawne rozmiesz-
Sloty
Gdy wybierzemy z menu Edit->Slots. ..,
ukaże się nam okienko, w którym będzie-
Tworzenie aplikacji
w polskiej wersji językowej
Tworząc oprogramowanie z wykorzysta-
niem Qt Designera można z powodze-
niem stosować polskie nazwy z polski-
mi znakami diakrytycznymi. W przypadku
napisów na przyciskach i w menu nie ma
z tym żadnego problemu. W przypadku
napisów (stringów) wpisanych w kodzie
programu, tj. tekst komunikatu, musimy
stosować się do pewnych reguł, aby pol-
skie znaki diakrytyczne były wyświetlane
prawidłowo. Po pierwsze, w konstruktorze
klasy (lub w funkcji init()), w której chcemy
używać polskich znaków, musimy wska-
zać kodowanie, które ma być używane w
programie. Służy do tego funkcja:
#include <qtextcodec.h>
[...]
QTextCodec::setCodecForTr( QText
Codec::codecForName("ISO8859-2") );
Następnie w kodzie programu, zawsze
gdy będziemy używać napisów w języku
polskim, będziemy opatrywać je funkcją
tr() . W przypadku komunikatu informa-
cyjnego może to wyglądać następująco:
QMessageBox::information
(this, tr("Ostrzeżenie"),
tr("Nie można uruchomić
procesu..."),
QmessageBox::Ok);
Rysunek 3. Łączenie sygnałów ze slotami
Zastosowanie funkcji tr() ma tę dodat-
kową zaletę, że na jej podstawie można
wygenerować pliki językowe, które stosu-
je się przy tworzeniu wersji językowych
programu.
26 luty 2006
439111984.018.png 439111984.019.png 439111984.020.png
 
439111984.021.png 439111984.022.png 439111984.023.png 439111984.024.png 439111984.025.png 439111984.026.png 439111984.027.png 439111984.028.png 439111984.029.png 439111984.030.png 439111984.031.png 439111984.032.png
 
programowanie w Qt
programowanie
my mogli zadeklarować dowolną funkcję
języka C++. Funkcje, które w ten sposób
utworzymy, zostaną w procesie kompila-
cji dodane do deinicji naszej klasy qtISOM-
Form i będą widoczne w pliku nagłówko-
wym .ui/qtisomform.h .
Okienko ( Edit Functions ), które teraz
mamy na ekranie, pozwala zdeiniować
wszystkie części funkcji, takie jak nazwa,
typ oraz zwracana wartość. Najbardziej
intrygujące będzie pewnie pole Type: , w
którym mamy do wyboru slot lub funk-
cję. Różnica polega na tym, że slot jest spe-
cyiczną funkcją, która może być połączo-
na z sygnałem wygenerowanym przez
użytkownika. Przykładem sygnału jest
np. kliknięcie na przycisku lub wybranie
jakieś pozycji z menu.
Listing 2. Kod wczytujący listę podkatalogów według pozycji startowej
void qtISOMForm :: readDir ( QString initDir , QListViewItem * parent ) {
QDir dir ( initDir );
dir . setFilter ( QDir :: All );
QStringList content = dir . entryList ();
QListViewItem * newItem ;
for ( QStringList :: Iterator it = content . begin ();
S
it != content . end (); ++ it ) {
if (( QString :: compare (* it , ".." ) != 0 )
&& ( QString :: compare (* it , "." ) != 0 )) {
QFileInfo ileinfo ( initDir + "/" + * it );
newItem = new QListViewItem ( parent , * it );
if ( ileinfo . isReadable () && ileinfo . isDir ())
newItem -> setPixmap ( 0 , QPixmap ( "images/dir.png" ));
if (! ileinfo . isReadable () && ileinfo . isDir ())
newItem -> setPixmap ( 0 , QPixmap ( "images/dirro.png" ));
if ( ileinfo . isFile ())
newItem -> setPixmap ( 0 , QPixmap ( "images/ile.png" ));
}
}
}
Connections
Gdy z menu Qt Designera wybierzemy
Edit->Connections , ukaże się nam okien-
ko, które służy do łączenia slotów (specjal-
nych funkcji) z sygnałami występującymi
w programie. Od razu zdeiniujemy jedno
połączenie, które doda do naszego progra-
mu pierwszą funkcjonalność. Po wciśnię-
ciu przycisku New ustawimy wszystkie
kolumny wg Rysunku 3.
W ten sposób od razu po skompilowa-
niu, program będzie zamykał się po wybra-
niu opcji Exit z menu. Nie jest to nic zna-
czącego, ale jak do tej pory nie wpisali-
śmy żadnej linii kodu. Podobnych ułatwień
w przypadku programowania z użyciem
Qt jest sporo.
tworzyć wszystkie deinicje metod, które
będą wykorzystywane w naszym progra-
mie. Mówiąc kolokwialnie, w tym miejscu
stworzymy całą mechanikę naszej aplikacji.
Listing 3. Slot powiązany z sygnałem
podwójnego kliknięcia na elemencie listy
void qtISOMForm :: lv1DbClicked
( QListViewItem * item ) {
if (( item -> irstChild () == 0 )
init()/destroy()
Oprócz opisanych powyżej zalet, two-
rzenia aplikacji w programie Qt Designer
ma również kilka wad. Jedną z nich jest
to, że nie mamy dostępu do konstruktora
i destruktora klasy okna. Tak więc wykona-
nie jakichś operacji zaraz po uruchomieniu
programu jest realizowane w inny sposób.
Mamy do tego dwie dodatkowe funkcje:
init() oraz destroy() . Aby można było
z nich skorzystać, należy je dodać w oknie
Edit Functions , które zostało już omówione.
W naszym programie będziemy potrzebo-
wać jedynie funkcji init() , więc tylko taką
funkcję musimy dodać. Klikamy przycisk
New function , a następnie w polu Function
wpisujemy init() i zatwierdzamy przy-
ciskiem OK . Po dodaniu tej funkcji będzie
ona widoczna w edytorze kodu.
S
&& (! item -> isOpen ())) {
QString tmpStr ;
if ( item != 0 ) {
if ( item -> parent () != 0 ) {
tmpStr = item -> text ( 0 );
QListViewItem * tmpItem =
S
Members
W prawym górnym rogu w programie
Qt Designer znajduje sie zakładka opi-
sana jako Members , w której deiniujemy
wszystkie części składowe klasy edyto-
wanego okna. Ta część została podzielo-
na na kilka elementów. Odpowiadają one
wszystkim częściom, które mogą wcho-
dzić w skład deinicji klasy w języku C++.
Na podstawie zawartości tego okna, jak i
naszej formatki, zostanie wygenerowany
plik nagłówkowy odpowiedzialny za cały
wygląd i funkcjonalność naszej aplikacji.
item ;
while ( tmpItem -> parent ()) {
tmpItem = tmpItem -> parent ();
tmpStr . prepend ( tmpItem
S
-> text ( 0 ) + "/" );
}
}
else {
tmpStr = item -> text ( 0 );
}
}
readDir ( "/" + tmpStr , item );
item -> setOpen ( true );
}
if (! item -> isOpen ()) {
item -> setOpen ( false );
}
else {
item -> setOpen ( true );
}
}
Drzewo katalogów
Aby nasz program był intuicyjny i pozwał
łatwo dodawać pliki do obrazu ISO, musi
zawierać listę katalogów i plików systemu.
Lista ta powinna być załadowana zaraz po
uruchomieniu programu. Zajmiemy się teraz
stworzeniem takiej właśnie funkcjonalności.
W pierwszym etapie dodamy plik
nagłówkowy qdir.h na samej górze w edy-
Edytor kodu
Gdy klikniemy dwukrotnie w dowolnym
miejscu okna naszej aplikacji (nie doty-
czy przycisków i innych kontrolek), zosta-
nie utworzony plik qtisomform.ui.h . Jego
wygenerowanie jest również możliwe po
wybraniu kombinacji klawiszy [ Ctrl ]+[ E ]. W
oknie, które wówczas się pojawi, będziemy
www.lpmagazine.org
27
439111984.033.png 439111984.034.png 439111984.035.png 439111984.036.png 439111984.037.png 439111984.038.png 439111984.039.png 439111984.040.png 439111984.041.png 439111984.042.png
programowanie
Listing 4. Metoda łączona z sygnałem
select()
Pętla for z Listingu 1 pozwala wycią-
gnąć pojedyncze nazwy z tak przygotowanej
listy nazw katalogów. Wykonujemy to przy
pomocy iteratorów (zaprezentowany przy-
kład użycia iteratora jest dość schematyczny
dla całego Qt i na tym etapie Czytelnik nie
musi wiedzieć więcej o tym zastosowaniu).
Pierwszą czynnością, którą wykonujemy
w pętli, jest sprawdzenie, czy nazwa kata-
logu jest różna od “.” oraz “..”. Zostało ono
dodane, gdyż metoda entryList() zwraca
listę również z tymi wartościami. W naszym
przykładzie są niepotrzebne.
Gdy wiemy, że kolejna wartość listy
nie jest “.” lub “..”, możemy dodać tę pozy-
cję do naszego ListView o nazwie listDir .
Dodanie polega na stworzeniu nowego
obiektu QListViewItem , którego rodzicem
(parent) jest listDir . Korzystamy tutaj
z konstruktora klasy QlistViewItem :
Można wykorzystać dowolne inne ikony,
ale jeśli będą miały inne nazwy i/lub będą
znajdować się w innych katalogach, należy
to uwzględnić w kodzie programu.
void
qtISOMForm :: lv1selChanged
( QListViewItem * item ) {
S
Poruszanie po katalogach
Samo załadowanie głównego drzewa kata-
logów systemu to trochę za mało do spraw-
nej obsługi programu. Dodamy teraz funk-
cję umożliwiającą poruszanie się po tych
katalogach. Mechanizm będzie polegał na
tym, że podwójne kliknięcie na wybranej
pozycji z drzewa powoduje rozwinięcie
wszystkich podkatalogów, które znajdu-
ją się w wybranej pozycji, o ile takowe się
znajdują. W pierwszej kolejności dodamy
kod wczytujący listę podkatalogów według
pozycji startowej podanej w parametrze
wywołania tej metody – Listing 2.
Slot, który połączymy z sygnałem
doubleClicked(QListViewItem * item) ,
będzie wyglądał jak na Listingu 3 (po-
winniśmy go dodać przy pomocy okienka
Slots , które zostało już omówione).
Kluczowym elementem tej funkcji
jest wczytanie nazw wszystkich rodzi-
ców wybranej pozycji. W ten sposób uzy-
skujemy całą ścieżkę drzewa, którą wyko-
rzystujemy w funkcji wczytującej podka-
talogi do kontrolki ListView . Od linii z if
(!item->isOpen ()) zaczyna się kod odpo-
wiedzialny za zwijanie lub rozwijanie list
w zależności od stanu tej pozycji (może
być rozwinięta lub zwinięta).
Teraz pozostaje jeszcze jedna czyn-
ność, czyli połączenie tego slota z sygna-
łem podwójnego kliknięcia na kontrolce
listDir . Powinno ono wyglądać następu-
jąco: listDir generuje sygnał doubleClic-
ked(QListViewItem * item) , który odbiera
qtISOMForm i wykonuje lv1DbClicked(QLi-
stViewItem * item) .
Na tym etapie może skompilować pro-
gram i przetestować jego działanie. Kom-
pilacja programów tworzonych z wyko-
rzystaniem biblioteki Qt opiera się na uru-
S
( item -> isSelected ())) {
if ( item -> parent () != 0 ) {
tmpStr = item -> text ( 0 );
QListViewItem * tmpItem = item ;
while ( tmpItem -> parent ()) {
tmpItem = tmpItem ->
S
S
( tmpItem -> text ( 0 ) + "/" );
}
}
else {
tmpStr = item -> text ( 0 );
}
selectedItem = "/" + tmpStr ;
}
}
QListViewItem ( QListView * parent,
S
S
QString label1, QString label2 =
S
QString::null, QString label3 =
S
QString::null, QString label4 =
S
QString::null, QString label5 =
S
QString::null, QString label6 =
S
torze kodu. W tym pliku zostały zdeinio-
wane wszystkie funkcje umożliwiające
poruszanie się po katalogach systemu, jak
i wczytywanie listy katalogów. Kod, który
wczyta listę katalogów systemu do kontrol-
ki ListView , będzie wyglądał tak jak na
Listingu 1.
Omawiany kod w pierwszej kolejno-
ści zmienia parametry kontrolki ListView .
Opcja rootIsDecorated jest również
dostępna w Qt Designerze. Ustawienie jej
na wartość true sprawia, że katalogi są
wyświetlane w postaci drzewa, a nie listy
(w przypadku ustawienia tej wartości na
false ). Zaraz po ustawieniu parametrów
wywołujemy funkcję mainDirRead , która
wczytuje wszystkie katalogi, które znaj-
dują się w głównym drzewie /. Funkcja ta
w pierwszej kolejności tworzy zmienną
dir , która jest klasą, której konstruktor
wygląda następująco:
QString::null, QString label7 =
S
QString::null, QString label8 =
QString::null )
Z zaprezentowanego powyżej konstrukto-
ra wynika, że musimy podać dwie pierw-
sze wartości. Wszystkie inne nie są koniecz-
ne, gdyż mają przypisane wartości domyśl-
ne. W dalszej części tej pętli dodaliśmy do
każdej pozycji ikonkę, w zależności od
typu danej pozycji. Sprawdzanie odbywa
się przy pomocy klasy QFileInfo , która
w konstruktorze dostaje wartość QString
z nazwą i ścieżką do obiektu, którego wła-
ściwości chcemy sprawdzić. Typ danego
obiektu jest określany w metodach isDir() ,
isFile() oraz isReadable() . Ikonki użyte
w programie są dołączone do kodów źró-
dłowych opisywanych w tym artykule.
Listing 5. Slot podłączany do sygnału clicked()
QDir ( const QString & path, const
S
void qtISOMForm :: addSelected () {
if ( selectedItem != "" ) {
listIso -> insertItem ( selectedItem , - 1 );
}
else {
QMessageBox :: information ( this , "Warning" ,
S
IgnoreCase, int ilterSpec = All )
null, int sortSpec = Name |
W ten sposób tworzymy zmienną, dzięki
której możemy wczytać listę wszystkich pod-
katalogów do zmiennej QStringList (lista
ciągów znaków), a następnie dowolnie ją
przeszukać i wyciągnąć to, co nas interesuje.
S
"You must select something!" , QMessageBox :: Ok );
}
}
28 luty 2006
QString tmpStr ;
selectedItem = "" ;
if (( item != 0 ) &&
parent ();
tmpStr . prepend
S
QString & nameFilter = QString::
439111984.043.png 439111984.044.png 439111984.045.png
 
439111984.046.png 439111984.048.png 439111984.049.png 439111984.050.png 439111984.051.png 439111984.052.png 439111984.053.png
 
Zgłoś jeśli naruszono regulamin