Getting Started with Qt/sl

From Qt Wiki
Revision as of 06:51, 24 February 2015 by Maintenance script (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

h1. Pričetek programiranja s Qt-om

Dobrodošli v svetu Qt-a – ogrodja za grafično programiranje za več platform. V tem začetnem vodiču se boste skozi implementacijo preprostega urejevalnika besedil naučili osnov Qt-a. Po zaključku branja tega vodiča boste pripravljeni, da se poglobite v branje pregledov tehnologij in dokumentacije programskega vmesnika ter tako najdete podatke, ki jih potrebujete za razvoj svoje aplikacije.

Pozdravljen Urejevalnik

V prvem primeru preprosto ustvarimo in prikažemo polje za urejanje besedila, ki se nahaja v oknu na namizju. To predstavlja najpreprostejši možni program Qt z grafičnim uporabniškim vmesnikom.

p=. Zaslonski posnetek urejevalnika

Tukaj je koda:

<br />#include &lt;QApplication&amp;gt;<br />#include &lt;QTextEdit&amp;gt;

int main(int argv, char *'''args)<br />{<br /> QApplication app(argv, args);
<br /> QTextEdit textEdit;<br /> textEdit.show();
<br /> return app.exec&amp;amp;#40;&amp;#41;;<br />}<br />


Pa se sprehodimo po vsaki vrstici kode. V prvih dveh vrsticah vstavimo datoteki z glavo za razreda "QApplication&quot;:http://doc.qt.nokia.com/latest/qapplication.html in "QTextEdit&quot;:http://doc.qt.nokia.com/latest/qtextedit.html, ki ju potrebujemo za ta primer. Vsi razredi v Qt imajo datoteko z glavo, ki ima enako ime kot ustrezen razred.


V 6. vrstici ustvarimo objekt razreda "QApplication&quot;:http://doc.qt.nokia.com/latest/qapplication.html. Ta objekt upravlja z viri za aplikacijo in je potreben za delovanje kateregakoli programa Qt, ki ima grafični uporabniški vmesnik. Parametra argv in args sta potrebna, ker Qt sprejme nekaj argumentov iz ukazne vrstice.
V 8. vrstici ustvarimo objekt razreda "QTextEdit&quot;:http://doc.qt.nokia.com/latest/qtextedit.html. Polje za urejanje besedila je v grafičnem uporabniškem vmesniku viden element. V Qt-u take elemente imenujemo gradniki. Primeri drugih gradnikov so drsniki, oznake in gumbi. Gradnik je lahko tudi vsebnik za druge gradnike. Tako je na primer pogovorno okno ali pa glavno okno programa.
V 9. vrstici polje za urejanje besedila prikažemo na zaslonu in sicer v svojem oknu. Ker gradniki služijo tudi kot vsebniki (npr. "QMainWindow&quot;:http://doc.qt.nokia.com/latest/qmainwindow.html, ki vsebuje orodjarne, menije, vrstico stanja in druge gradnike), je posamezen gradnik moč prikazati v svojem oknu. Gradniki privzeto niso vidni. S klicem funkcije "show()":http://doc.qt.nokia.com/latest/qwidget.html#show postane gradnik viden.
V 11. vrstici zaženemo dogodkovno zanko objekta app, ki je razreda "QApplication&quot;:http://doc.qt.nokia.com/latest/qapplication.html. Med tekom programa Qt se sprožajo dogodki, ki se pošiljajo gradnikom programa. Primera dogodkov sta pritisk na gumb miške in pritisk tipke. Ko v gradnik polja za urejanje besedila tipkate besedilo, le-ta prejme dogodke pritiskov tipk in se odzove z izrisom natipkanega besedila.


Da zaženete program, odprite ukazno vrstico in se postavite v mapo, ki vsebuje datoteko.cpp z izvorno kodo programa. Naslednji ukazi zgradijo program:

<br />qmake -project<br />qmake<br />make<br />


Po tem bo v mapi ustvarjena izvršljiva datoteka (v Windows morate morda namesto make uporabiti nmake, izvršljiva datoteka pa bo v mapi debug ali release). qmake je Qt-ovo orodje za gradnjo, ki kot vhod sprejme nastavitveno datoteko (s končnico
.pro). qmake le-to ustvari za nas,če mu podamo možnost -project. Pisanje lastnih nastavitvenih datotek si bomo ogledali kasneje.


h3. Naučite se več
|. Tema|. Tu|
|Gradniki in geometrija oken|"Window and Dialog Widgets&quot;:http://doc.qt.nokia.com/latest/application-windows.html%7C
|Dogodki in ravnanje z dogodki|"The Event System&quot;:http://doc.qt.nokia.com/latest/eventsandfilters.html%7C



h2. Dodajanje gumba Končaj
V pravi aplikaciji boste običajno potrebovali več kot en gradnik. Sedaj bomo pod polje za urejanje besedila dodali gumb razreda "QPushButton&quot;:http://doc.qt.nokia.com/latest/qpushbutton.html. Ko uporabnik pritisne (klikne z miško) na gumb, se bo program končal.
p=. Urejevalnik s gumbom Končaj


Pa si oglejmo kodo:

<br />#include &lt;QtGui&amp;gt;
<br />int main(int argv, char'''*args)<br />{<br /> QApplication app(argv, args);

QTextEdit textEdit;<br /> QPushButton quitButton(&quot;Končaj&amp;quot;);

QObject::connect(&amp;quitButton, SIGNAL (clicked()), qApp, SLOT (quit()));

QVBoxLayout layout;<br /> layout.addWidget(&amp;textEdit);<br /> layout.addWidget(&amp;quitButton);

QWidget window;<br /> window.setLayout(&amp;layout);

window.show();

return app.exec&amp;amp;#40;&amp;#41;;<br />}<br />


V 1. vrstici vstavimo "QtGui&quot;:http://doc.qt.nokia.com/latest/qtgui.html, ki vsebuje vse Qt-ove razrede za grafični uporabniški vmesnik.

V 10. vrstici uporabimo Qt-ov mehanizem signalov in rež, s čimer omogočimo da se ob pritisku gumba Končaj aplikacija konča. Reža je funkcija, ki jo lahko prek njenega imena (kot literalenega niza) sprožimo med izvajanjem. Signal je funkcija, ki bo ob klicu sprožila reže, ki so registrirane pri njej. To imenujemo povezovanje reže s signalom in oddajanje signala.

Funkcija "quit()":http://doc.qt.nokia.com/latest/qcoreapplication.html#quit je reža razreda "QApplication&quot;:http://doc.qt.nokia.com/latest/qapplication.html, ki konča aplikacijo. Funkcija "clicked()":http://doc.qt.nokia.com/latest/qabstractbutton.html#clicked je signal, ki je del razreda "QPushButton&quot;:http://doc.qt.nokia.com/latest/qpushbutton.html in se odda, ko je gumb pritisnjen. Statična funkcija "QObject::connect()":http://doc.qt.nokia.com/latest/qobject.html#connect poskrbi za povezavo reže s signalom. SIGNAL () in SLOT() sta dva nakra, ki sprejmeta podpisa funkcij signala in reže, ki bosta povezana. Podati moramo tudi kazalca na objekta, ki bosta poslala in prejela signal.

V 12. vrstici ustvarimo razpored razreda "QVBoxLayout&quot;:http://doc.qt.nokia.com/latest/qvboxlayout.html. Kot smo že omenili, lahko gradniki vsebujejo druge gradnike. Omejitve (položaj in velikost) vsebovanih gradnikov je moč nastaviti neposredno, vendar je običajno preprosteje uporabiti razpored. Razpored upravlja z omejitvami gradnikovih podgradnikov. "QVBoxLayout&quot;:http://doc.qt.nokia.com/latest/qvboxlayout.html podgradnike razporedi v stolpec.

V 13. in 14. vrstici urejevalno polje in gumb dodamo v razpored. V 17. razpored nastavimo na glavnem gradniku.

Naučite se več
|. Tema|. Tu|
|Signali in reže|"Signals and Slots&quot;:http://doc.qt.nokia.com/latest/signalsandslots.html%7C
|Razporedi|"Layout Management&quot;:http://doc.qt.nokia.com/latest/layout.html, "Widgets and Layouts&quot;:http://doc.qt.nokia.com/latest/widgets-and-layouts.html, "Layout Examples&quot;:http://doc.qt.nokia.com/latest/examples-layouts.html%7C
|Gradniki, ki pridejo s Qt|"Qt Widget Gallery&quot;:http://doc.qt.nokia.com/latest/gallery.html, "Widget Examples&quot;:http://doc.qt.nokia.com/latest/examples-widgets.html%7C

Izdelava podrazreda QWidget

Morda bi želeli, da se, ko uporabnik želi končati program, prikaže pogovorno okno, ki ga vpraša, če to res želi storiti. V tem primeru bomo izdelali podrazred razreda "QWidget&quot;:http://doc.qt.nokia.com/latest/qwidget.html in dodali režo, ki jo bomo povezali z gumbom Končaj.

p=. Urejevalnik z dedovanjem od QWidget

Pa si oglejmo kodo:

<br />class Notepad : public QWidget<br />{<br /> Q_OBJECT

public:<br /> Notepad();

private slots:<br /> void quit();

private:<br /> QTextEdit *textEdit;<br /> QPushButton *quitButton;<br />};<br />


Macro Q_OBJECT mora biti v definiciji razreda prvi in določa, da je naš razred "QObject&quot;:http://doc.qt.nokia.com/latest/qobject.html (seveda mora tudi dedovati od QObject). "QObject&quot;:http://doc.qt.nokia.com/latest/qobject.html običajnemu razredu C++ doda množico zmožnosti. Na primer, v času izvajanja lahko poizvedujemo po imenu razreda in imenih rež. Poizvedovati je možno tudi po tipih parametrov reže in jo izvesti.

V 13. vrstici deklariramo režo quit(). To je s pomočjo makra slots preprosto. Režo quit() lahko sedaj povežemo s signali, ki imajo ustrezen podpis (vsak signal, ki ne potrebuje nobenega parametra).

Namesto da bi postavili grafični uporabniški vmesnik in povezali režo v funkciji main(), uporabimo konstruktor razreda Notepad.

<br /> Notepad::Notepad()<br /> {<br /> textEdit = new QTextEdit;<br /> quitButton = new QPushButton(tr(&quot;Končaj&amp;quot;));

connect(quitButton, SIGNAL (clicked()), this, SLOT (quit()));

QVBoxLayout '''layout = new QVBoxLayout;<br /> layout-&gt;addWidget(textEdit);<br /> layout-&gt;addWidget(quitButton);
<br /> setLayout(layout);
<br /> setWindowTitle(tr(&quot;Urejevalnik&amp;quot;));<br /> }<br />


Kot smo videli v definiciji razreda, uporabljamo kazalce do naših "QObject&quot;:http://doc.qt.nokia.com/latest/qobject.html-ov (textEdit in quitButton). Kot splošno pravilo: "QObject&quot;:http://doc.qt.nokia.com/latest/qobject.html-e naj bi vedno ustvarjali na kopici in jih nikoli kopirali.


Sedaj okoli uporabniku vidnih nizov uporabimo funkcijo "tr()":http://doc.qt.nokia.com/latest/qobject.html#tr. Ta funkcija je potrebna, če želite svoj program ponuditi v več jezikih (npr. še v angleščini in kitajščini). Tu se ne bomo spuščali v podrobnosti, lahko pa sledite povezavi Qt Linguist v tabeli Naučite se več.
h3. Ustvaritev datoke .pro


Za ta primer bomo napisali datoteko .pro po meri in ne bomo uporabili qmake-ove možnosti project.

<br /> HEADERS = notepad.h<br /> SOURCES = notepad.cpp  main.cpp<br />


Naslednji ukazi zgradijo primer:

<br /> qmake<br /> make<br />


h3. Naučite se več:
|. Tema|. Tu|
|tr() in internacionalizacija|"Qt Linguist Manual&quot;:http://doc.qt.nokia.com/latest/linguist-manual.html, "Writing Source Code for Translation&quot;:http://doc.qt.nokia.com/latest/i18n-source-translation.html, "Hello tr() Example&quot;:http://doc.qt.nokia.com/latest/linguist-hellotr.html, "Internationalization with Qt&quot;:http://doc.qt.nokia.com/latest/internationalization.html%7C
|"QObject&quot;:http://doc.qt.nokia.com/latest/qtwebkit-bridge.html#qobjects-i in Qt-ov objektni model (to je osnovno za razumevanje Qt-a)|"Object Model&quot;:http://doc.qt.nokia.com/latest/object.html%7C
|qmake in Qt-ov sistem za gradnjo|"qmake Manual&quot;:http://doc.qt.nokia.com/latest/qmake-manual.html%7C



h2. Uporaba QMainWindow
Za veliko programov bo koristno, če uporabite "QMainWindow&quot;:http://doc.qt.nokia.com/latest/qmainwindow.html, ki ima svoj lasten razpored, v katerega lahko dodate menijsko vrstico, podokna, orodjarne in vrstico stanja. "QMainWindow&quot;:http://doc.qt.nokia.com/latest/qmainwindow.html ima osrednje področje, ki ga lahko zapolnjuje katerikoli gradnik. V našem primeru bo to naše urejevalno polje.
p=. Urejevalnik s QMainWindow


Pa si oglejmo novo definicijo razreda Notepad:

<br /> #include &lt;QtGui&amp;gt;
<br /> class Notepad : public QMainWindow<br /> {<br /> Q_OBJECT
<br /> public:<br /> Notepad();
<br /> private slots:<br /> void open();<br /> void save();<br /> void quit();
<br /> private:<br /> QTextEdit *textEdit;
<br /> QAction *openAction;<br /> QAction *saveAction;<br /> QAction *exitAction;
<br /> QMenu '''fileMenu;<br /> };<br />


Dodamo dve novi reži za odpiranje in shranjevanje dokumenta. Reži bomo implementirali v naslednjem razdelku.


Pogosto se zgodi, da želimo v glavnem oknu isto režo izvesti iz več gradnikov. Primera sta menijski vnos in gumb orodjarne. Da bi bilo to čim lažje, Qt ponuja razred "QAction&quot;:http://doc.qt.nokia.com/latest/qaction.html, ki ga lahko podamo več gradnikom in je povezan z režo. Na primer, "QMenu&quot;:http://doc.qt.nokia.com/latest/qmenu.html in "QToolBar&quot;:http://doc.qt.nokia.com/latest/qtoolbar.html lahko menijske vnose in gumbe orodjarne ustvarita iz istih "QAction&quot;:http://doc.qt.nokia.com/latest/qaction.html-ov. Kmalu bomo videli, kako to deluje.


Kot prej bomo za postavitev uporabniškega vmesnika uporabili konstruktor Notepad-a

<br /> Notepad::Notepad()<br /> {<br /> saveAction = new QAction(tr(&quot;&amp;Odpri &quot;), this);<br /> saveAction = new QAction(tr(&quot;&amp;Shrani&amp;quot;), this);<br /> exitAction = new QAction(tr(&quot;Konča&amp;amp;j&amp;quot;), this);
<br /> connect(openAction, SIGNAL (triggered()), this, SLOT (open()));<br /> connect(saveAction, SIGNAL (triggered()), this, SLOT (save()));<br /> connect(exitAction, SIGNAL (triggered()), qApp, SLOT (quit()));
<br /> fileMenu = menuBar()<s>&gt;addMenu(tr(&quot;&amp;Datoteka&amp;quot;));<br /> fileMenu</s>&gt;addAction(openAction);<br /> fileMenu-&gt;addAction(saveAction);<br /> fileMenu-&gt;addSeparator();<br /> fileMenu-&gt;addAction(exitAction);
<br /> textEdit = new QTextEdit;<br /> setCentralWidget(textEdit);
<br /> setWindowTitle(tr(&quot;Urejevalnik&amp;quot;));<br /> }<br />


"QAction&quot;:http://doc.qt.nokia.com/latest/qaction.html-e ustvarimo z besedilom, ki se pojavi na gradnikih, za katere uporabimo QAction-e (v našem primeru so to menijski vnosi). Če bi jih želeli uporabiti tudi za orodjarne, bi dejanjem lahko dodali tudi "ikone&quot;:http://doc.qt.nokia.com/latest/qicon.html.


Ko sedaj uporabnik klikne na menijski vnos, bo vnos sprožil dejanje in izvedla se bo ustrezna reža.
h3. Naučite se več:
|. Tema|. Tu|
|Glavna okna in razredi glavnih oken|"Application Main Window&quot;:http://doc.qt.nokia.com/latest/mainwindow.html, "Main Window Examples&quot;:http://doc.qt.nokia.com/latest/examples-mainwindow.html%7C
|Program z vmesnikom z več dokumenti|"QMdiArea&quot;:http://doc.qt.nokia.com/latest/qmdiarea.html, "MDI Example&quot;:http://doc.qt.nokia.com/latest/mainwindows-mdi.html%7C



h2. Odpiranje in shranjevanje
V tem primeru bomo implementirali delovanje rež open() in save(), ki smo ju dodali v prejšnjem primeru.
p=. Pogovorno okno za odpiranje datotek


Zaželi bomo z režo open():

<br /> QString fileName = QFileDialog::getOpenFileName(this, tr(&quot;Odpiranje datoteke&amp;quot;), &quot;&quot;,<br /> tr(&quot;Besedilne datoteke ('''.txt);;Datoteke C++ ('''.cpp'''.h)&quot;));
<br /> if (fileName != &quot;&quot;) {<br /> QFile file&amp;amp;#40;fileName&amp;amp;#41;;<br /> if (!file.open(QIODevice::ReadOnly)) {<br /> QMessageBox::critical(this, tr(&quot;Napaka&amp;quot;),<br /> tr(&quot;Datoteke ni bilo moč odpreti&amp;quot;));<br /> return;<br /> }<br /> QString contents = file.readAll().constData();<br /> textEdit</s>&gt;setPlainText(contents);<br /> file.close();<br /> }<br />


V prvem koraku uporabnika vprašamo po imenu datoteke, ki bo odprta. Qt prihaja s "QFileDialog&quot;:http://doc.qt.nokia.com/latest/qfiledialog.html, ki je pogovorno okno, iz katerega lahko uporabnik izbere datoteko. Gornja slika prikazuje pogovorno okno na namizju KDE Plasma na Linuxu. Statična funkcija "getOpenFileName()":http://doc.qt.nokia.com/latest/qfiledialog.html#getOpenFileName prikaže pogovorno okno, ki je vedno nad vsemi programovimi okni in ne vrne nič, dokler uporabnik ne izbere datoteke. Pogovorno okno vrne polno pot do izbrane datoteke ali pa prazen niz, če je uporabnik preklical pogovorno okno.


Če imamo ime datoteke, datoteko poskušamo odpreti z "open()":http://doc.qt.nokia.com/latest/qiodevice.html#open, ki vrne true, če je bilo datoteko moč odpreti. V podrobnosti rokovanja z napakami se tu ne bomo spuščali, lahko pa sledite povezavam v tabeli Naučite se več. Če datoteke ni bilo moč odpreti, uporabimo "QMessageBox&quot;:http://doc.qt.nokia.com/latest/qmessagebox.html in prikažemo pogovorno okno s sporočilom o napaki (za nadaljnje podrobnosti si oglejte opis "QMessageBox&quot;:http://doc.qt.nokia.com/latest/qmessagebox.html-a).
Dejanjsko branje podatkov je zahvaljujoč funkciji "readAll()":http://doc.qt.nokia.com/latest/qiodevice.html#readAll preprosto. Funkcija vse podatke iz datoteke vrne v objektu "QByteArray&quot;:http://doc.qt.nokia.com/latest/qbytearray.html. Funkcija "constData()":http://doc.qt.nokia.com/latest/qbytearray.html#constData vse podatke vrne kot const char, za kar ima "QString&quot;:http://doc.qt.nokia.com/latest/qstring.html konstruktor. Vsebino potem lahko prikažemo v urejevalnem polju. Nazadnje še zapremo datoteko s klicem funkcije "close()":http://doc.qt.nokia.com/latest/qiodevice.html#close in tako opisovalnik datoteke vrnemo operacijskemu sistemu.

Nadaljujmo še z režo save():

<br /> QString fileName = QFileDialog::getSaveFileName(this, tr(&quot;Shranjevanje datoteke&amp;quot;), &quot;&quot;,<br /> tr(&quot;Besedilne datoteke ('''.txt);;Datoteke C++ ('''.cpp '''.h)&quot;));
<br /> if (fileName != &quot;&quot;) {<br /> QFile file&amp;amp;#40;fileName&amp;amp;#41;;<br /> if (!file.open(QIODevice::WriteOnly)) {<br /> // sporočilo o napaki<br /> } else {<br /> QTextStream stream(&amp;file);<br /> stream &lt;&lt; textEdit-&gt;toPlainText();<br /> stream.flush();<br /> file.close();<br /> }<br /> }<br />


Za zapisovanje vsebine urejevalnega polja v datoteko uporabimo razred "QTextStream&quot;:http://doc.qt.nokia.com/latest/qtextstream.html, ki ovija objekt "QFile&quot;:http://doc.qt.nokia.com/latest/qfile.html. Besedilni tok lahko nize "QString&quot;:http://doc.qt.nokia.com/latest/qstring.html zapisuje neposredno v datoteko. "QFile&quot;:http://doc.qt.nokia.com/latest/qfile.html s funkcijo "write()":http://doc.qt.nokia.com/latest/qiodevice.html#write iz "QIODevice&quot;:http://doc.qt.nokia.com/latest/qiodevice.html sprejema le surove podatke (char).

Naučite se več
|. Tema|. Tu|
|Datoteke in V/I naprave|"QFile&quot;:http://doc.qt.nokia.com/latest/qfile.html, "QIODevice&quot;:http://doc.qt.nokia.com/latest/qiodevice.html%7C