2005.02_KDevelop–narzędzie do tworzenia aplikacji z interfejsem graficznym_[Programowanie].pdf
(
545 KB
)
Pobierz
439110678 UNPDF
narzędzia deweloperskie
KDevelop
– narzędzie do tworzenia
aplikacji z interfejsem
graicznym
Marek Sawerwain
narzędzie i sprawdzić, czy
będzie ono przydatne w pra-
cy, dobrze jest wykorzystać
je do realizacji jakiegoś zadania. Załóż-
my, że chcemy napisać niewielką apli-
kację, która będzie stanowił graficzną
nakładkę na program
Wget
.
KDE
oferuje
nam bardzo dobry program dla progra-
mistów o nazwie
KDevelop
. W tym arty-
kule pokażemy, jak z jego pomocą osią-
gnąć zdefiniowany powyżej cel, a tym
samym udowodnimy, że jest on aplikacją
godną polecenia.
jest poznanie adresu pliku – zakładamy,
że zostanie on podany przez użytkow-
nika. Następnie, gdy dysponujemy już
adresem, jesteśmy gotowi do wywoła-
nia programu
Wget
. KDE oferuje gotową
klasę o nazwie
KProcess
, która wspoma-
ga to zadanie. Jej najważniejszą właści-
wością jest fakt, iż pozwala w łatwy
Instalacja programu
KDevelop
Ponieważ już sporo czasu upłynęło od
wydania wersji 3.0 programu, to więk-
szość dystrybucji Linuksa oferuje ten
program – wystarczy tylko zainstalować
pakiet zawierający KDevelopa.
Po instalacji może okazać się, iż nie
możemy wywołać opcji
Uruchom auto-
make
. Okazuje się, że KDevelop wymaga
do poprawnej pracy wersji Automake
wyższej niż 1.6, a Autoconf wyższej niż
2.5. Problem ten pojawia się np. w wersji
Mandrakelinux 10.1, ale rozwiązanie jest
bardzo proste – wystarczy doinstalować
odpowiednie pakiety.
Z użytkowaniem KDevelopa wiąże
się też inny problem, gdyż po utworzeniu
projektu i wykonaniu z nim jakichś prac,
może okazać się, że KDevelop nie chce
ponownie wczytać naszej pracy, generu-
jąc sygnał 11. Rozwiązaniem jest skaso-
wanie w katalogu projektu dwóch plików:
pierwszy posiada rozszerzenie
kdevses
,
a drugi
pcs
.
Podczas instalacji KDevelopa warto
upewnić się, czy zainstalowana zostanie
dokumentacja, gdyż omawiane narzę-
dzie ma bardzo dobry moduł do doku-
mentacji, który bardzo przydaje się pod-
czas pisania jakiejkolwiek aplikacji, nawet
tak prostej jak nasz projekt.
Na płycie CD/DVD
Na płycie CD/DVD znajduje się
kod źródłowy programu oraz
wszystkie listingi z artykułu.
Kilka założeń na początek
Interfejs naszego programu będzie pre-
zentował się bardzo skromnie. Wystarczą
nam dwa przyciski: jeden do zamknięcia
okna oraz drugi, którym rozpoczniemy
proces ściągania pliku. Będziemy rów-
nież potrzebowali komponentu o typie
QLineEdit
, którego nazwiemy
Address-
Text
. Umieścimy w nim adres pliku,
który chcemy ściągnąć. Ponieważ pobie-
ranie pliku zrealizujemy za pomocą innej
aplikacji (co więcej, będzie ona działała
w trybie konsoli), to będziemy musieli
przechwytywać standardowe wyjście, na
które
Wget
wysyła wszelkie komunikaty
podczas swojej pracy. Wykorzystamy do
tego celu komponent o typie
QtextEdit
,
którego nazwiemy
MessageBoxText
.
Jak zawsze, warto przygotować nie-
wielki schemat, w którym przedstawi-
my najważniejsze zdarzenia, które będą
zachodzić w naszym programie. Został
on przedstawiony na Rysunku 1. Jak
widać, proces ściągania pliku składa się
z kilku pomniejszych zadań. Pierwszym
O autorze
Autor zajmuje się tworzeniem
oprogramowania dla WIN32
i Linuksa. Zainteresowania: teoria
języków programowania oraz
dobra literatura.
Kontakt z autorem:
autorzy@lpmagazine.org
22
luty 2005
G
dy chcemy poznać jakieś
kdevelop
narzędzia deweloperskie
Rysunek 2.
Tworzenie nowego projektu
Rysunek 1.
Główne zdarzenia pojawiające się w programie
Projektujemy formularz
Po utworzeniu projektu przygotujemy
w pierwszej kolejności okno formula-
rza. W górnym oknie
Menadżera auto-
make
(z prawej strony głównego okna
z kodem) wybieramy gałąź z naszym pro-
jektem, czyli
wget_gui
, a następnie kata-
log
src
. Gdy w dolnym oknie
Menadże-
ra automake
klikniemy prawym przyci-
skiem myszy na dowolnym pliku, pokaże
się nam małe menu z kilkoma opcjami.
Wybieramy opcję
Utwórz nowy plik...
.
Zobaczymy takie okno, jak na Rysunku 3.
Do pola
Nazwa pliku
wpisujemy np.
wget_gui_widget.ui
, a następnie wybiera-
my typ pliku –
Widget
. Tworzymy widget,
który zostanie podłączony do głównego
okna naszej aplikacji. Okno tworzenia
tego pliku można także uzyskać wybie-
rając z menu
Plik
opcję
Nowy
.
Po wykonaniu tej operacji jeste-
śmy gotowi do utworzenia interfejsu za
pomocą
QtDesignera
. Niestety, jeśli uży-
wamy nowej wersji KDevelopa, to po
dwukrotnym kliknięciu na pliku
wget_
gui_widget.ui
, uruchomi się tylko prze-
glądarka
KUIViewer
, a nam jest potrzeb-
ny QtDesigner. W tym celu wystarczy
prawym przyciskiem myszy wybrać pod-
menu
Otwórz w
i z opcji, które się nam
wyświetlą, wybrać
Projektanta Qt
.
Ułożenie dwóch przycisków (
Push-
Button
z sekcji
Buttons
okna
Toolbox
)
oraz dwóch komponentów (
LineEdit
i
TextEdit
z sekcji
Input
) nie powinno
nikomu sprawić trudności, ale trzeba
odpowiednio zadeklarować sygnały.
sposób przechwycić dane kierowane
na standardowe wyjście (ang.
stdout
)
oraz na standardowe wyjście o błędach
(ang.
stderr
), co czasem również może
się przydać.
jeszcze raz przycisk
Następny
. Zobaczy-
my okno, w którym znajduje się tekst
licencji. Będzie on dołączany do każde-
go pliku nagłówkowego. Jeśli chcemy,
aby do każdego takiego pliku były dołą-
czane inne informacje, w tym miejscu
możemy to zmienić. Gdy naciśniemy raz
jeszcze przycisk
Następny
, to tym razem
przycisk zmieni etykietę na
Koniec
i po
jego naciśnięciu zostanie wygenerowa-
ny podstawowy szkielet projektu.
Zanim zaczniemy go kompilować,
należy jeszcze wykonać dwie czynności.
Z okna
Buduj
wybieramy opcję
Uruchom
Automake
. Po kilku chwilach, gdy pro-
gram utworzy wszystkie skrypty, z tego
samego menu
Buduj
wybieramy opcję
Uruchom Configure
. Wszystkie komuni-
katy będą wyświetlane w okienku na
dole programu. Dopiero po zakończe-
niu działania skryptu
configure
możemy
dokonać kompilacji projektu naciska-
jąc klawisz [
F8
] lub wybierając z menu
Buduj
opcję
Buduj projekt
. Utworzony
program uruchomiamy wciskając klawi-
sze [
Shift
]+[
F9
] – z menu
Buduj
opcja
Wykonaj program
.
Tworzymy projekt
Pierwszym krokiem jest utworzenie
nowego projektu w KDevelop. Nasz
program piszemy dla środowiska KDE,
więc po uruchomieniu programu prze-
chodzimy do menu
Projekt
. Wybie-
ramy z niego
Nowy projekt...
. Pokaże
się okno podobne do tego z Rysun-
ku 2. Na liście odszukujemy gałąź
C++
,
a następnie KDE, gdzie znajduje-
my pozycję
Simple KDE Application
.
We
Właściwościach
musimy podać
Nazwę Aplikacji
. Załóżmy, że projekt
będzie nazywał się
wget_gui
. Pozosta-
łe pola mają dla nas mniejsze znaczenie.
Wybieramy teraz przycisk
Następny
, aby
przejść do następnego okna, w którym
będziemy mogli wybrać system kon-
troli wersji. Nam nie jest on potrzebny,
gdyż tworzona przez nas aplikacja nie
wymaga pracy grupowej. Wybieramy
Rysunek 3.
Tworzenie pliku formularza
www.lpmagazine.org
23
narzędzia deweloperskie
Listing 1.
Implementacja konstruktora wget_gui, w którym tworzymy formularz programu
#
include
"wget_gui.h"
#include
<qlabel.h>
#include
<kmainwindow.h>
#include
<klocale.h>
#
include
"wgetguiwidget.h"
Rysunek 5.
Tworzenie pliku podklasy
wget_gui
::
wget_gui
()
:
KMainWindow
(
0
,
"wget_gui"
)
{
// set the shell's ui resource file
setXMLFile
(
"wget_guiui.rc"
);
wystarczy wpisać dość podobne wyraże-
nie tworzące nasz formularz:
// new QLabel( "Hello World", this, "hello label" );
new
wgetGuiWidget
(
this
,
"wget gui"
,
0
);
}
new wgetGuiWidget(this, "wget gui", 0);
wget_gui
::
~
wget_gui
()
{
}
W ten sposób, po kompilacji programu,
zamiast etykiety zobaczymy zaprojek-
towany przez nas formularz. Jak widać,
zmiany mają charakter tylko kosmetycz-
ny. Zaletą takiego podejścia jest fakt, że
nie musimy wprowadzać żadnych zmian
w funkcji
main
. Kod, który został tam
wygenerowany, możemy pozostawić bez
zmian.
#
include
"wget_gui.moc"
Z menu
Edit
wybieramy pozycję
Slots...
i deklarujemy dwie funkcje:
Download-
BTN_Slot()
oraz
CloseAppBTN_Slot()
.
Następnie wciskamy klawisz [
F3
] i kli-
kamy myszką na formularzu. Wywo-
łujemy okno
View and Edit Connec-
tions
, w którym, tak jak to widać na
Rysunku 4, podłączamy sygnały
clicked
to dwóch funkcji odpowiadających
za przyciski ściągania oraz zakończe-
nia pracy aplikacji (nadawcą jest odpo-
wiedni przycisk, a odbiorcą – formularz,
czyli okno).
Po utworzeniu pliku w formacie
ui
przystępujemy do generowania tzw.
pliku podklasy. Ta czynność także zosta-
ła w pełni zautomatyzowana. Wybiera-
my plik
ui
z okna
Menadżera automa-
ke
i prawym przyciskiem myszy wywo-
łujemy menu, z którego wybieramy opcję
Element podklas...
. Pokaże się takie okno,
jak na Rysunku 5.
Jedyne, co musimy zrobić, to wpisać
nazwę klasy:
wgetGuiWidget
, bowiem
nazwa pliku uzupełni się samodzielnie.
Zwróćmy też uwagę na listę z metodami
– są tam nasze funkcje (sloty), które zde-
finiowaliśmy w programie QtDesigner.
Jeśli na liście nie zostały wymienione
powyższe sloty, to niestety trzeba prze-
rwać generowanie podklasy i powrócić
do QtDesignera, aby naprawić ten błąd.
Przycisk kończący pracę
programu
W tym momencie możemy zająć się
obsługą dwóch przycisków, które znaj-
dują się w naszym programie. Ich imple-
mentacja jest zawarta w pliku
wgetgu-
iwidget.cpp
. Jest to ten sam plik podkla-
sy (ang.
subclass),
który wygenerowa-
liśmy na podstawie formularza z pliku
wget_gui_widget.ui
.
Zaczniemy od przycisku, którego
zadaniem jest zamknięcie aplikacji. Jak
łatwo się domyśleć, jest to bardzo łatwe
do wykonania. Na początku pliku dołą-
czamy dodatkowe pliki nagłówkowe:
Pierwsze poprawki
Projekt, który utworzyliśmy, zawie-
ra tylko jeden widget, a jest nim ety-
kieta
Hello World
. Należy w jakiś
sposób podmienić ten widget na formu-
larz, który przygotowaliśmy wcześniej
w programie QtDesigner. W pierwszej
kolejności otwieramy plik o nazwie
wget_gui.cpp
. Zobaczymy plik o treści
podobnej do Listingu 1. Na początku
dołączamy plik nagłówkowy formularza,
który został przez nas zaprojektowany:
#include <qapplication.h>
#include <kapplication.h>
Znajdują się w nich klasy reprezentujące
całą aplikację.
W każdej aplikacji KDE mamy dostęp
do obiektu
kapp
, który reprezentuje
obiekt aplikacji. Wywołanie metody
quit
spowoduje zamknięcie całego programu.
W naszej aplikacji funkcję do zamknięcia
programu nazwaliśmy
CloseAppBTN_Slot
.
Implementacja tej metody sprowadza
się do wywołania metody
quit
z obiek-
ty
kapp
:
#include "wgetguiwidget.h"
Następnie, w samym konstruktorze,
zamiast linii tworzącej etykietę:
Rysunek 4.
Projektowanie interfejsu oraz
podłączanie sygnałów i funkcji
new QLabel( "Hello World", this,
S
"hello label" );
24
luty 2005
kdevelop
narzędzia deweloperskie
Listing 2.
Implementacji metody
DownloadBTN_Slot
, odpowiedzialnej za ściągnięcie pliku
zgodnie z tym, co podałem powyżej, jest
następujący:
void
wgetGuiWidget
::
DownloadBTN_Slot
()
{
KProcess
*
task
;
Reader
reader
;
*task << "wget –progress=dot";
*task << AddressText->text();
MessageBoxText
->
append
(
">>> process begin <<<"
);
Adres pliku jest odczytywany z wid-
getu
AddressText
. Warto jeszcze usta-
lić, jaki typ powłoki zostanie użyty
do wywołania polecenia
wget
. Doko-
nujemy tego metodą
setUseShell
. Kod,
który wykonuje tę czynność, jest nastę-
pujący:
task
=
new
KProcess
;
*
task
<<
"wget –progress=dot"
;
*
task
<<
AddressText
->
text
();
task
->
setUseShell
(
true
,
"/bin/sh"
);
reader
.
edt
=
MessageBoxText
;
QApplication
::
connect
(
task
,
SIGNAL
(
receivedStdout
(
KProcess
*
,
char
*
,
int
))
,
&
reader
,
SLOT
(
read_stdout
(
KProcess
*
,
char
*
,
int
)));
task->setUseShell(true, "/bin/sh");
W tym momencie moglibyśmy uru-
chomić nasz proces metodą
start
, ale
wszystkie komunikaty z programu
wget
są skierowane na konsolę, z której uru-
chomiamy program. Jeśli robimy to
z poziomu środowiska graficznego, to
nie zobaczymy żadnych komunikatów.
Z tego powodu należy przechwycić
wszystkie dane kierowane na strumie-
nie
stdout
oraz
stderr
. Wykorzystujemy
w tym celu obiekt
reader
. Aby mógł on
poprawnie wykonywać swoje działanie,
należy do pola
edt
skopiować wskaźnik
na komponent
QTextEdit
o nazwie
Mes-
sageBoxText
:
QApplication
::
connect
(
task
,
SIGNAL
(
receivedStderr
(
KProcess
*
,
char
*
,
int
))
,
&
reader
,
SLOT
(
read_stderr
(
KProcess
*
,
char
*
,
int
)));
if
(
task
->
start
(
KProcess
::
Block
,
Kprocess
::
AllOutput
))
{
MessageBoxText
->
append
(
">>> process end <<<"
);
}
else
{
MessageBoxText
->
append
(
">>> process failed <<<"
);
}
}
void wgetGuiWidget::CloseAppBTN_Slot(){
kapp->quit();
}
który musimy utworzyć, aby wykonać
polecenie
wget
. Bardzo istotna jest rów-
nież druga zmienna –
reader
. Jest to zde-
finiowana przez nas klasa, która jest nam
potrzebna, aby przechwytywać dane ze
standardowego wyjścia.
W następnej linii umieszczamy komu-
nikat tekstowy o tym, że proces wywoła-
nia
wget
właśnie się rozpoczyna.
Teraz możemy przystąpić do właści-
wego zadania. Tworzymy obiekt
task
:
reader.edt=MessageBoxText;
Ściąganie pliku
Oprogramowanie drugiego przycisku to
nasze główne zadanie. Będziemy odwo-
ływać się do innych komponentów, więc
konieczne jest dołączenie odpowiednich
plików nagłówkowych. Ponieważ stosu-
jemy pola edycji o typie
QLineEdit
oraz
QTextEdit
, to dołączamy następujące pliki
nagłówkowe:
Następnym zadaniem do wykonania jest
podłączenie sygnału przeznaczonego do
odbioru danych skierowanych na stan-
dardowe strumienie przez obiekt typu
KProcess
. Wykonujemy je metodą
con-
nect
z klasy
QApplication
. Kod z Listin-
gu 2, wykorzystując obiekt
reader
, prze-
chwytuje dane ze standardowego wyj-
ścia oraz ze standardowego wyjścia
o błędach.
Podłączenie sygnału dla pierwsze-
go przypadku wygląda w następujący
sposób:
task=new KProcess;
#include <qlineedit.h>
#include <qtextedit.h>
Po jego utworzeniu możemy usta-
lić postać wywołania polecenia
wget
.
Zakładamy, że będzie ono wywoływane
w następujący sposób:
Jak już wcześniej wspomniałem, wy-
korzystujemy również klasę
KProcess
,
więc będzie nam potrzebny plik
nagłówkowy
kprocess.h
. Po tych
wstępnych czynnościach przystępuje-
my do implementacji funkcji
Downlo-
adBTN_Slot
. Listing 2 zawiera jej pełny
kod źródłowy.
Pierwszym krokiem jest zadeklarowa-
nie dwóch zmiennych. Pierwsza z nich,
task
, reprezentuje proces zewnętrzny,
QApplication::connect(task,
SIGNAL(receivedStdout
(KProcess *, char *, int)),
&reader,
SLOT(read_stdout(KProcess *, char *,
S
int )));
wget --progress=dot
S
http://www.adres.com.pl/katalog/plik.zip
Wielką zaletą klasy
KProcess
jest moż-
liwość składania polecenia z fragmen-
tów za pomocą przeciążonego operato-
ra
<<
. Pierwszy fragment, co jest oczywi-
ste, musi zawierać nazwę polecenia. Kod,
w którym budujemy postać polecenia,
Polecenie dla strumienia
stderr
jest
bardzo podobne.
Używając
QApplication::connect
sięgamy do wewnętrznych mechani-
www.lpmagazine.org
25
narzędzia deweloperskie
Listing 3.
Plik nagłówkowy klasy
Reader
AllOutput
. Pierwsza wartość oznacza,
że nasza aplikacja zostanie zatrzymana
na czas wykonania się polecenia
wget
.
Druga wartość oznacza, że będzie-
my przechwytywać wszelkie informa-
cje kierowane do standardowych stru-
mieni wyjściowych. Gdyby istniała
potrzeba zarządzania standardowym
wejściem, to podajemy wartość
KPro-
cess::Stdin
. Gdyby istniała potrzeba
kontrolowania wszystkich trzech
standardowych strumieni, to należy
w metodzie
start
podać stałą
KPro-
cess::All
.
Jak widać na Listingu 2, wywoła-
nie jest objęte instrukcją warunkową.
Jeśli metoda zwróci logiczną prawdę,
to oznacza to, że proces zewnętrzny
zakończył się prawidłowo i plik został
poprawnie ściągnięty. Wbrew pozo-
rom, w ten sposób uzyskaliśmy gotowy
program, który jest nieskomplikowa-
ną nakładką na polecenie
wget
. Do
implementacji pozostała jeszcze klasa
Reader
.
#include
<kapplication.h>
#include
<kprocess.h>
#include
<qtextedit.h>
#include
<qobject.h>
class
Reader
:
public
QObject
{
Q_OBJECT
public
:
Reader
(
QObject
*
parent
=
0
,
const
char
*
name
=
0
);
~
Reader
();
QTextEdit
*
edt
;
public
slots
:
void
read_stdout
(
KProcess
*
p
,
char
*
b
,
int
l
);
void
read_stderr
(
KProcess
*
p
,
char
*
b
,
int
l
);
}
;
zmów, więc ważne są parametry, które
podajemy w przypadku tej metody.
Pierwszym jest obiekt, który będzie
generował sygnał – nasz obiekt
task
.
W drugim określamy rodzaj sygna-
łu. Zwróćmy uwagę na nazwę funk-
cji:
receivedStdout
. W przypadku stru-
mienia
stderr
nazwa funkcji w defini-
cji sygnału jest następująca:
received
Stderr
. W obu przypadkach funkcja
odpowiadająca na sygnał przyjmuje te
same parametry.
W trzecim argumencie metody
con-
nect
wskazujemy obiekt, który będzie
odbierał sygnał –
reader
.
W ostatnim parametrze musimy wska-
zać metodę, która zostanie wywołana
z obiektu
reader
w odpowiedzi na sygnał.
W nomenklaturze Qt/KDE metoda odpo-
wiadająca na sygnał nazywa się slotem,
więc w ostatnim parametrze stosujemy
makro
SLOT
.
Po podłączeniu obu sygnałów
możemy uruchomić program
wget
,
wywołując metodę
start
z obiektu
task
. Do przechwycenia danych wysy-
łanych do
stdout
i
stderr
w metodzie
start
trzeba podać dodatkowe parame-
try:
KProcess::Block
oraz
KProcess::
Klasa Reader
Listing 3 prezentuje plik nagłówkowy
klasy
Reader
. Jest to, jak widać, klasa dzie-
dzicząca z klasy
QObject
, co jest koniecz-
ne, aby poprawnie funkcjonował mecha-
nizm sygnałów i slotów. Nie należy doda-
wać jej samodzielnie do projektu, gdyż
Listing 4.
Implementacja klasy
Reader
#
include
"reader.h"
#include
<kprocess.h>
Reader
::
Reader
(
QObject
*
parent
,
const
char
*
name
)
:
QObject
(
parent
,
name
)
{
}
void
Reader
::
read_stdout
(
KProcess
*
p
,
char
*
b
,
int
l
)
{
edt
->
append
(
QString
::
fromLatin1
(
b
,
l
));
}
void
Reader
::
read_stderr
(
KProcess
*
p
,
char
*
b
,
int
l
)
{
edt
->
append
(
QString
::
fromLatin1
(
b
,
l
));
}
Reader
::
~
Reader
()
{
}
Rysunek 6.
Tworzenie klasy Reader
#
include
"reader.moc"
26
luty 2005
Plik z chomika:
SOLARIX33
Inne pliki z tego folderu:
2006.01_Koder plików w formacie OGG_[Programowanie].pdf
(722 KB)
2007.06_Piękno fraktali_[Programowanie].pdf
(1778 KB)
2008.11_GanttProject_[Programowanie].pdf
(1014 KB)
2007.04_USB Device Explorer_[Programowanie].pdf
(1134 KB)
2006.09_QT, PyQT – szybkie tworzenie baz danych_[Programowanie].pdf
(1319 KB)
Inne foldery tego chomika:
Administracja
Aktualnosci
Audio
Bazy Danych
Bezpieczenstwo
Zgłoś jeśli
naruszono regulamin