Qt - Hello World

Од Сподели wiki
Прејди на: содржини, барај


KDE и Qt програмирање

Покрај основните Qt библиотеки во работата на KDE постојат и други библиотеки, едноставно наречени KDE библиотеки. Разлика има во методите, во променливите што се дефинирани во класите, како и во очигледната разлика на имињата на класите. Едните (Qt класите) започнуваат со буквата „Q“ додека имињата на КDE класите започнуваат во буквата K. На пример, KApplication, QApplication, KMessageBox, QMessageBox...и т.н.

Стручните лица кои работат на развој на KDE софтвер, препорачуваат да се користат KDE класите при изработка на софтвер за KDE, и како eдинствена причина ја наведуваат, задржување на начинот на функционирање, имплементации, па се до изгледот на апликациите. Ќе забележите понатаму дека програмите кои ги изработувате, нема да се разликуваат од останатите. Ќе ги имаат истите копчиња, истите прозорци, истите можности итн. Како поедноставен пример започнуваме со вообичаената прва програма во сите програмски јазици. Hello Qt World.

Hello Qt World

Лично кога се работи за изучување на било кој јазик, јас преферирам код како пример за да видам, што е напишано и зошто е тоа така. Најпрво би го побарал Hello World кодот, па претпоставувам дека тоа го делам со повеќемина. Започнувам со едноставен код кој што на екранот ќе извади прозорче со копче на кое ќе пишува Hello World. Напрво ги користиме двете вклучни датотеки qapplication.h и qpushbutton.h. Потоа следува дефинирање на главната main() функција. Потоа телото на тоа што сакаме да се изврши. Кодот би изгледал вака:

 #include <qapplication.h>
 #include <qpushbutton.h>
void main(int argc, char** argv) {
QApplication a(argc, argv);
QPushButton hello(“Hello World”, 0); hello.resize(120, 40);
a.setMainWidget(&hello); hello.show(); return a.exec();
}

Првите препроцесори ги вклучуваат qapplication.h и qpushbutton.h, во кои се дефинирани класите потребни за апликацијата. Пример во првата вклучна датотека се дефинирани фонотови, видови на покажувачи (за глувчето), методи кои важат за повеќе објекти на класи наследници на QApplication и друго. Во нашиот случај кодот ги користи класите QАpplication и QPushButton. Аргументите во главната main() функција се argc и argv. Првиот е бројот на аргументите што се задаваат во командниот ред при компајлирање на кодот, а другиот е низа во која се сместуваат тие аргументи. Следната линија, QApplication a(argc, argv); дефинира објект oд тип QАpplication. Потоа следува QPushButton hello(“Hello World”, 0);, дефиниција на објект “hello”, oд тип QPushButton, кој има два аргументи, првиот е стринг т.е. тоа што треба да го пишува на копчето, но не и името на копчето, името е дадено преку името на објектот, во случајот “hello”. Вториот аргумент е 0, што ни кажува дека објектот hello, во прозорчето треба да си е самостоен објект, да го завзема целотo прозорче. Во случај да наместо 0 стои име на друг објект, тогаш објектот hello ќе биде сместен во тој објект (Повеќе за фамилијата на Qt ќе зборуваме понатаму). Пример, hello(“Hello World”, &box), каде box е претходно дефиниран објект, да речиме од класа QVBox (подетално за овие работи во следните продолженија каде ќе пишувам за фамилиите на Qt апликациите). Одиме натаму и стигнуваме до hello.resize(120, 40); со што му задаваме големина на копчето (објектот) hello. Доколку овој ред не постои тогаш копчето ќе си биде со стандардните димензии, минимално (0,0). Методот “resize” (дефиниран во QApplication), како и што се гледа прима два аргументи, должината на X и Y координатите на копчето, во пиксели. Следните три линии од кодот се наоѓаат речиси во сите Qt кодови, ако не вака како што се дадени овде, барем слично. (12) e ред со кој како главен објект во прозорчето (објектот) “а” го поставуваме објектот “hello”, кој го дефиниравме претходно. Не е задолжително поставување на главен објект во некој прозорец, но најчесто тоа е случај. За да стане видлив објектот “hello”, му правиме hello.show(); инаку по дефинирањето, т.е. креирањето, тој е невидлив објект. Методот еxec() е дефиниран во QApplication и покрај тоа што треба да ја врати извршената вредност на “a” (дефиниран според погорните редови) исто работа му е да си чека (да врти, loop) додека не е повикана друга функција, од типот на exit() или quit() при што враќа 0 или 1. Кодот е веќе спремен за превод.

Преведување на Qt код

Прво треба да се направи датотека hello.pro, која претставува проект за кодот, за која ќе направиме Makefile. Доколку сте го зачувале кодот во датотека hello.cpp, која сте ја сместиле во директориум hello тогаш, за да се компајлира извршна датотека, одете во директориумот hello па преку команда “qmake -project” се создава датотеката hello.pro (бараната проект-датотека), потоа преку команда “qmake -o Makefile hello.pro” во истиот директориум се создава датотека Мakefile, и на крај со „make“ ја „правиме“ извршната датотека. Сето тоа ако e во ред треба да изгледа вака:

 # cd hello
 # qmake -project
 # qmake -o Makefile hello.pro
 # make
 g++ -c -pipe -Wall -W -O2 -D QT_NO_DEBUG -I/usr/local/qt/mkspecs/default -I. -I. -I 
 /usr/local/qt/include -o hello.o hello.cpp
 g++ -o hello hello.o -Wl,-rpath,/usr/local/qt/lib -L/usr/local/qt/lib -L/usr/X11R6/lib -lqt -lXext -lX11 -lm
 # ./hello

Редовите што се појавуваат под „make” не јавуваат грешка, такашто ако ја стартуваме извршната датотека ./hello, ќе го добиеме посакуваниот прозорец. Начинот за компајлирање е речиси секогаш идентичен, се зависи од тоа што сакаме и каде, да добиеме. Постојат и други варијации на командата qmake за правење на Makefile или проект-датотека, кои подоцна ќе ги разгледаме, а исто така за преведување на вашите програми најкористен метод меѓу програмерите е средината за развој KDevelop. Конфигурирање, изработка и се друго што е потребно за да функционира вашата програма, сето тоа автоматизирано. Причината што постои овој принцип за превод на програми, е компатибилноста на програмите со различни оперативни системи и платформи. Едноставно на овој начин корисникот ќе биде известен дека има грешка во тоа и тоа, дека треба да се направи тоа и тоа и се разбира тоа не секогаш е случај на решение. Да не навлегувам уште од сега подлабоко, програмите ќе ги преведуваме како што објаснав погоре, со некои додатни измени. Посвојствен начин за преведување на вашите програми е преку qmake бидејќи и таа команда е дел од Qt.

Содржина на Makefile и Проект-датотеката

Makefile

Кога ќе ја направите (генерирате) Makefile датотеката, во неа се сместуваат некои команди кои треба да се извршат пред да се преведи кодот, се задаваат вредности на глобални променливи и сл. Истите тие можат да се извршат и преку конзола, т.е. да ги извршите како едноставни *nix команди. Што ви кажува тоа? Се разбира, Makefile претставува шел скрипта, која има за цел да посочи каде се наоѓаат одредени директориуми, кои датотеки треба да се преведуваат, каде се наоѓаат вклучните датотеки кои се вклучени во вашата програма и слично. Тука се правилата според кои можете да го завршите процесот на преведување, да ја од-инсталирате програмата, или да направите clean или distclean, со што ќе се исчистат претходните конфигурирања кои се направени (на пример преку скриптата configure). И покрај тоа што содржи и други команди најбитни се двете променливи кои примаат патеки до одредени директориуми:

 # QTDIR=/usr/local/lib
 # KDEDIR=/usr/lib/kde

Во првиот ред се дефинира директориумот каде што се наоѓаат Qt библиотеките, а во вториот ред се дефинира пак директориумот каде што се наоѓаат вашите KDE библиотеки и другите потребни датотеки. Кога ќе направите make можете да забележите дека при преведувањето, преведувачот не ги користи целите патеки, ами само овие две променливи. Исто така понатаму во оваа датотека се дефинирани местата каде што се изворните датотеки за проектот, кој преведувач се користи, суфиксите на датотеките и слични други работи.

Оние кои се запознати со работата на Linux базираните оперативни системи, знаат и што се g++ и gcc. Тоа се првичните преведувачи за gcc.

gcc/g++ кои доаѓаат со Linux кернелот уште од самиот почеток. Ние не ги користиме директно, меѓутоа кога ќе ја извршиме командата make, се повикуваат овие преведувачи.

Проект-датотеката hello.pro

Ова што ќе го објаснам, во глобала важи и за останатите проект-датотеки. Малите разлики лежат во тоа какви програми се напишани и за што би се користеле тие. На пример, нашата програма hello користи проект-датотека (hello.pro), која ја формиравме погоре, и која ја има следната содржина:

  1. TEMPLATE = app
  2. CONFIG -= moc
  3. INCLUDEPATH += .
  4. # Input
  5. SOURCES += hello.cpp

Што сето ова значи? Во првиот ред (1) како шаблон (анг. Template) се користи app, а како конфигурациона (2) алатка МОС (повеќе за овие алатки и шаблони/шеми во следите делови на упатствата). Директориумот каде што се вклучени хедерите се одредува во третиот ред (3), во случајот тоа е точка, тековниот директориум. Во четвртиот ред (4) му кажуваме на преведувачот, која е изворната датотека што треба да ја преведе.

Интегрирана Развојна Средина или Дизајнер?

За време на вашето програмирање и целосно продлабочување во концептите и начините на работа со Qt ќе сфатите дека постојат полесни начини за пишување на кодот, од тој што вие го користите. Или пак, потешки принципи за кои ќе се прашувате „Зошто да го користам тоа, кога со ова е полесно?“.

Но една работа или непишано правило гласи: Со тоа што ќе започнете, со тоа и ќе продолжите. За да работите со KDevelop од постарите верзии (пред да излезе Qt 4.0) мора да го пишувате целиот код. Мора да ги правите вашите програми целосно пишувајќи ја секоја линија. За нашата последна програма тоа е сосема лесно, таа се состои од мал број линии на код, но замислете дека правите клиент за е-пошта. Како би изгледало да го пишувате тој код рачно. И што ако некои линии се повторуваат за секој ваш проект? Нели би било полесно тој код да се генерира од друга алатка/програма, која едноставно ви ја олеснува работата максимално. Таква алатка е Qt Designer, едноставна, брза, стабилна, со сите можности што ги нуди Qt како целина. Формите ги генерирате, копчињата и другите слични објекти ги цртате, а функционирањето на програмата ја пишувате вие. Се е визуелно. Но тоа е сепак дизајнер, не е IDE. Дизајнерот работи со UI датотеки (пример form1.ui), во кои сместува XML код, кој дефинира форма, имиња, својства и слично. UI доаѓа од User Interface (мкд. кориснички интерфејс). Овие датотеки, со оваа наставка, се генерираат од самиот Дизајнер. Датотеките во кои вие го пишувате кодот, методите, слотовите, конструктори, деструктори, и друго, се со наставка .ui.h (пример form1.ui.h) и се наоѓаат таму каде што ќе ги зачувате (предефинирано се зачувуваат во тековниот директориум. Исто таму се зачувуваат и UI датотеките).

Во тековниот директориум на вашата програма, постојат три (предефинирани) под-директориуми. Dir/.ui (1), Dir/.obj (2) и Dir/.moc (3). Првиот (1) е генериран од Дизајнерот и во него се сместини датотеките во кои е извршена декларација и имплементација на употребените класи/променливи во нашиот проект. Вториот (2) директориум ги „прибира“ објектите креирани при преводот или мета поврзувањето на објектите. Во третиот (3) се ставени датотеки потребни и генерирани од МОС алатката, како и датотеки во кои е извршено поврзување на сигналите и слотовите (за сигнали-слотови ќе зборуваме покасно). Значи да заокружиме дека најголем дел од примерите овде, ќе бидат работени преку Дизајнерот. Се активира преку конзола:

 # designer &

или пак од некое мени. Локација на оваа алатка е $QTDIR/bin/designer.