Getting Started on the Commandline/uk: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
 
(7 intermediate revisions by 3 users not shown)
Line 1: Line 1:
[toc align_right="yes" depth="3"]
{{Cleanup | reason=Auto-imported from ExpressionEngine.}}
 


= Перші кроки з Qt =
= Перші кроки з Qt =
Line 9: Line 10:
В цьому першому прикладі ми просто створимо та відобразимо текстовий редактор у вікні на стільниці. Це буде найпростіша можлива програма Qt, що має ГІК.
В цьому першому прикладі ми просто створимо та відобразимо текстовий редактор у вікні на стільниці. Це буде найпростіша можлива програма Qt, що має ГІК.


p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs1.png|http://doc.qt.nokia.com/4.7/images/gs1.png]]
[[Image:http://doc.qt.io/qt-4.8/images/gs1.png|http://doc.qt.io/qt-4.8/images/gs1.png]]


Код програми:
Код програми:


<code><br />#include &lt;QApplication&amp;gt;<br />#include &lt;QTextEdit&amp;gt;
<code>
#include <QApplication>
#include <QTextEdit>
 
int main(int argc, char **argv)
{
QApplication app(argc, argv);
 
QTextEdit textEdit;
textEdit.show();
 
return app.exec();
}
</code>
 
Давайте переглянемо код рядок за рядком. В перших двох рядках ми підключаємо файли заголовків для [http://doc.qt.io/qt-4.8/qapplication.html QApplication] та [http://doc.qt.io/qt-4.8/qtextedit.html QTextEdit], двох класів, що потрібні для цього прикладу. Усі класи Qt мають файл заголовків, названий так само як і клас.
 
В рядку 6 створюється об'єкт [http://doc.qt.io/qt-4.8/qapplication.html QApplication]. Цей об'єкт керує ресурсами програми і має бути запущений в будь-який програмі Qt, що має ГІК. Йому передаються '''argc''' та '''argv''', оскільки Qt обробляє деякі параметри командного рядка.
 
В рядку 8 створюється об'єкт [http://doc.qt.io/qt-4.8/qtextedit.html QTextEdit]. Текстовий редактор є візуальним елементом ГІК. Ми називаємо такі елементи віджетами в Qt. Прикладами інших віджетів є панелі прокрутки, мітки та перемикачі. Віджет також може бути контейнером для інших віджетів, як, наприклад, діалог або головне вікно програми.
 
В рядку 9 текстовий редактор відображується на екрані у його власному вікні. Оскільки віджети також функціонують як контейнери (наприклад, [http://doc.qt.io/qt-4.8/qmainwindow.html QMainWindow], який має панелі інструментів, меню, рядок статусу та декілька інших віджетів), то можна відобразити один віджет у його власному вікні. Віджети не відображаються за замовчанням; функція [http://doc.qt.io/qt-4.8/qwidget.html#show show()] робить віджет видимим.
 
В рядку 11 відбувається вхід до циклу подій [http://doc.qt.io/qt-4.8/qapplication.html QApplication]. Коли програма Qt виконується, генеруються події, що доставляються до віджетів програми. Прикладами подій є натискання на кнопки миші та клавіші клавіатури. Коли ви набираєте текст в віджеті текстового редактора, він отримує події натискання клавіш та реагує промальовуванням тексту, що набирається.
 
Щоб запустити програму, відкрийте командний рядок та перейдіть до теки, в якій знаходиться файл '''.cpp''' програми. Наступні команди оболонки зберуть програму.
 
<code>
qmake -project
qmake
make
</code>
 
При цьому виконуваний модуль з'явиться в теці '''part1''' (майте на увазі, що у Windows вам, можливо, потрібно буде використовувати '''nmake''' замість '''make'''. Також, виконуваний модуль буде розміщено в '''part1/debug''' або '''part1/release'''). '''qmake''' - це інструмент збірки з Qt, який використовує конфігураційний файл. '''qmake''' генерує його для нас, коли запускається з аргументом '''-project'''. Коли конфігураційний файл (із суфіксом '''.pro''') існує, '''qmake''' створює файл збірки, який збирає для вас програму. Ми розглянемо написання власних файлів '''.pro''' пізніше.
 
=== Дізнайтесь більше ===
table{border:1px solid lightgray}.
{background:lightgray }. |''. Про |''. Тут |
|Віджети та геометрія вікна|'''[http://doc.qt.io/qt-4.8/application-windows.html'''| Віджети вікна та діалогу]
|Події та обробка подій|'''[http://doc.qt.io/qt-4.8/eventsandfilters.html'''| Система подій]
 
== Додаємо кнопку виходу ==
В справжній програмі вам, зазвичай, буде потрібен більше ніж один віджет. Зараз ми додамо [http://doc.qt.io/qt-4.8/qpushbutton.html QPushButton] нижче текстового редактора. Кнопка буде здійснювати вихід з програми Нотатник, коли на неї будуть натискати (наприклад, клацнуть мишею).
 
[[Image:http://doc.qt.io/qt-4.8/images/gs2.png|http://doc.qt.io/qt-4.8/images/gs2.png]]
 
Давайте поглянемо на код.
 
<code>
#include <QtGui>
 
int main(int argv, char **args)
{
QApplication app(argv, args);
 
QTextEdit textEdit;
QPushButton quitButton("Quit");
 
QObject::connect(&quitButton, SIGNAL (clicked()), qApp, SLOT (quit()));
 
QVBoxLayout layout;
layout.addWidget(&textEdit);
layout.addWidget(&quitButton);
 
QWidget window;
window.setLayout(&layout);
 
window.show();


int main(int argc, char *'''argv)<br />{<br /> QApplication app(argc, argv);
return app.exec();
<br /> QTextEdit textEdit;<br /> textEdit.show();
}
<br /> return app.exec&amp;amp;#40;&amp;#41;;<br />}<br /></code>
</code>
<br />p. Давайте переглянемо код рядок за рядком. В перших двох рядках ми підключаємо файли заголовків для &quot;QApplication&amp;quot;:http://doc.qt.nokia.com/4.7/qapplication.html та &quot;QTextEdit&amp;quot;:http://doc.qt.nokia.com/4.7/qtextedit.html, двох класів, що потрібні для цього прикладу. Усі класи Qt мають файл заголовків, названий так само як і клас.
 
<br />p. В рядку 6 створюється об'єкт &quot;QApplication&amp;quot;:http://doc.qt.nokia.com/4.7/qapplication.html. Цей об'єкт керує ресурсами програми і має бути запущений в будь-який програмі Qt, що має ГІК. Йому передаються &lt;code&amp;gt;argc&amp;lt;/code&amp;gt; та &lt;code&amp;gt;argv&amp;lt;/code&amp;gt;, оскільки Qt обробляє деякі параметри командного рядка.
Рядок 1 включає [http://doc.qt.io/qt-4.8/qtgui.html QtGui], який містить усі класи ГІК Qt.
<br />p. В рядку 8 створюється об'єкт &quot;QTextEdit&amp;quot;:http://doc.qt.nokia.com/4.7/qtextedit.html. Текстовий редактор є візуальним елементом ГІК. Ми називаємо такі елементи віджетами в Qt. Прикладами інших віджетів є панелі прокрутки, мітки та перемикачі. Віджет також може бути контейнером для інших віджетів, як, наприклад, діалог або головне вікно програми.
 
<br />p. В рядку 9 текстовий редактор відображується на екрані у його власному вікні. Оскільки віджети також функціонують як контейнери (наприклад, &quot;QMainWindow&amp;quot;:http://doc.qt.nokia.com/4.7/qmainwindow.html, який має панелі інструментів, меню, рядок статусу та декілька інших віджетів), то можна відобразити один віджет у його власному вікні. Віджети не відображаються за замовчанням; функція &quot;show()&quot;:http://doc.qt.nokia.com/4.7/qwidget.html#show робить віджет видимим.
В рядку 10 використовується механізм сигналів та слотів Qt, щоб завершити програму, коли натискається '''кнопка Вихід'''. Слот- це функція, що може бути викликана під час виконання програми за допомогою її назви (як рядкового літералу). Сигналом є функція, яка під час свого виклику, виконає слоти зареєстровані до неї; ми називаємо це "під'єднати слот до сигналу та видати сигнал".
<br />p. В рядку 11 відбувається вхід до циклу подій &quot;QApplication&amp;quot;:http://doc.qt.nokia.com/4.7/qapplication.html. Коли програма Qt виконується, генеруються події, що доставляються до віджетів програми. Прикладами подій є натискання на кнопки миші та клавіші клавіатури. Коли ви набираєте текст в віджеті текстового редактора, він отримує події натискання клавіш та реагує промальовуванням тексту, що набирається.
 
<br />p. Щоб запустити програму, відкрийте командний рядок та перейдіть до теки, в якій знаходиться файл &lt;code&amp;gt;.cpp&amp;lt;/code&amp;gt; програми. Наступні команди оболонки зберуть програму.
[http://doc.qt.io/qt-4.8/qcoreapplication.html#quit quit()] є слотом [http://doc.qt.io/qt-4.8/qapplication.html QApplication], який завершує програму. [http://doc.qt.io/qt-4.8/qabstractbutton.html#clicked clicked()] є сигналом, який [http://doc.qt.io/qt-4.8/qpushbutton.html QPushButton] видає, коли натискається. Статична функція [http://doc.qt.io/qt-4.8/qobject.html#connect QObject::connect]() піклується про з'єднання слота із сигналом. SIGNAL() та SLOT() - це два макроси, що приймають сигнатури функцій сигналу та слота, що з'єднуються. Також ми повинні передати вказівники на об'єкти, що мають надіслати та отримати сигнал.
<br /><code><br />qmake <s>project<br />qmake<br />make<br /></code>
 
<br />p. При цьому виконуваний модуль з'явиться в теці &lt;code&amp;gt;part1&amp;lt;/code&amp;gt; (майте на увазі, що у Windows вам, можливо, потрібно буде використовувати &lt;code&amp;gt;nmake&amp;lt;/code&amp;gt; замість &lt;code&amp;gt;make&amp;lt;/code&amp;gt;. Також, виконуваний модуль буде розміщено в &lt;code&amp;gt;part1/debug&amp;lt;/code&amp;gt; або &lt;code&amp;gt;part1/release&amp;lt;/code&amp;gt;). &lt;code&amp;gt;qmake&amp;lt;/code&amp;gt;</s> це інструмент збірки з Qt, який використовує конфігураційний файл. &lt;code&amp;gt;qmake&amp;lt;/code&amp;gt; генерує його для нас, коли запускається з аргументом &lt;code&amp;gt;<s>project&amp;lt;/code&amp;gt;. Коли конфігураційний файл (із суфіксом &lt;code&amp;gt;.pro&amp;lt;/code&amp;gt;) існує, &lt;code&amp;gt;qmake&amp;lt;/code&amp;gt; створює файл збірки, який збирає для вас програму. Ми розглянемо написання власних файлів &lt;code&amp;gt;.pro&amp;lt;/code&amp;gt; пізніше.
В рядку 12 створюється [http://doc.qt.io/qt-4.8/qvboxlayout.html QVBoxLayout]. Як вже згадувалось, віджети можуть містити інші віджети. Можна встановити границі (розташування та розмір) дочірніх віджетів безпосередньо, однак, зазвичай легше використати компонувальник. Компонувальник керує границями дочірніх віджетів. Наприклад, [http://doc.qt.io/qt-4.8/qvboxlayout.html QVBoxLayout] розташовує дітей у вертикальному рядку.
<br />h3. Дізнайтесь більше
 
<br />table{border:1px solid lightgray}.<br />{background:lightgray }. |''. Про |''. Тут |<br />|Віджети та геометрія вікна|'''&quot;Віджети вікна та діалогу&amp;quot;:http://doc.qt.nokia.com/4.7/application-windows.html'''|<br />|Події та обробка подій|'''&quot;Система подій&amp;quot;:http://doc.qt.nokia.com/4.7/eventsandfilters.html'''|
Рядки 13 та 14 додають текстовий редактор до компонувальника. В рядку 17 ми встановлюємо конмпонувальник на віджет.
<br />h2. Додаємо кнопку виходу
 
<br />p. В справжній програмі вам, зазвичай, буде потрібен більше ніж один віджет. Зараз ми додамо &quot;QPushButton&amp;quot;:http://doc.qt.nokia.com/4.7/qpushbutton.html нижче текстового редактора. Кнопка буде здійснювати вихід з програми Нотатник, коли на неї будуть натискати (наприклад, клацнуть мишею).
=== Дізнайтесь більше ===
<br />p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs2.png|http://doc.qt.nokia.com/4.7/images/gs2.png]]
table{border:1px solid lightgray}.
<br />p. Давайте поглянемо на код.
{background:lightgray }. |''. Про |''. Тут |
<br /><code><br />#include &lt;QtGui&amp;gt;
|Сигнали та слоти|'''[http://doc.qt.io/qt-4.8/signalsandslots.html*| Сигнали та слоти]
<br />int main(int argv, char **args)<br />{<br /> QApplication app(argv, args);
|Компонування|'''[http://doc.qt.io/qt-4.8/layout.html Управління компонуванням]''', '''[http://doc.qt.io/qt-4.8/widgets-and-layouts.html Віджети та компонування]''', '''[http://doc.qt.io/qt-4.8/examples-layouts.html'''| Приклади компонування]
<br /> QTextEdit textEdit;<br /> QPushButton quitButton(&quot;Quit&amp;quot;);
|Віджети, що входять до Qt|'''[http://doc.qt.io/qt-4.8/gallery.html Галерея віджетів Qt]''', '''[http://doc.qt.io/qt-4.8/examples-widgets.html'''| Приклади віджетів]
<br /> QObject::connect(&amp;quitButton, SIGNAL (clicked()), qApp, SLOT (quit()));
<br /> QVBoxLayout layout;<br /> layout.addWidget(&amp;textEdit);<br /> layout.addWidget(&amp;quitButton);
<br /> QWidget window;<br /> window.setLayout(&amp;layout);
<br /> window.show();
<br /> return app.exec&amp;amp;#40;&amp;#41;;<br />}<br /></code>
<br />p. Рядок 1 включає &quot;QtGui&amp;quot;:http://doc.qt.nokia.com/4.7/qtgui.html, який містить усі класи ГІК Qt.
<br />p. В рядку 10 використовується механізм сигналів та слотів Qt, щоб завершити програму, коли натискається '''кнопка Вихід'''. Слот</s> це функція, що може бути викликана під час виконання програми за допомогою її назви (як рядкового літералу). Сигналом є функція, яка під час свого виклику, виконає слоти зареєстровані до неї; ми називаємо це &quot;під'єднати слот до сигналу та видати сигнал&amp;quot;.
<br />p. &quot;quit()&quot;:http://doc.qt.nokia.com/4.7/qcoreapplication.html#quit є слотом &quot;QApplication&amp;quot;:http://doc.qt.nokia.com/4.7/qapplication.html, який завершує програму. &quot;clicked()&quot;:http://doc.qt.nokia.com/4.7/qabstractbutton.html#clicked є сигналом, який &quot;QPushButton&amp;quot;:http://doc.qt.nokia.com/4.7/qpushbutton.html видає, коли натискається. Статична функція &quot;QObject::connect&amp;quot;:http://doc.qt.nokia.com/4.7/qobject.html#connect() піклується про з'єднання слота із сигналом. SIGNAL&amp;amp;#40;&amp;#41; та SLOT&amp;amp;#40;&amp;#41; - це два макроси, що приймають сигнатури функцій сигналу та слота, що з'єднуються. Також ми повинні передати вказівники на об'єкти, що мають надіслати та отримати сигнал.
<br />p. В рядку 12 створюється &quot;QVBoxLayout&amp;quot;:http://doc.qt.nokia.com/4.7/qvboxlayout.html. Як вже згадувалось, віджети можуть містити інші віджети. Можна встановити границі (розташування та розмір) дочірніх віджетів безпосередньо, однак, зазвичай легше використати компонувальник. Компонувальник керує границями дочірніх віджетів. Наприклад, &quot;QVBoxLayout&amp;quot;:http://doc.qt.nokia.com/4.7/qvboxlayout.html розташовує дітей у вертикальному рядку.
<br />p. Рядки 13 та 14 додають текстовий редактор до компонувальника. В рядку 17 ми встановлюємо конмпонувальник на віджет.
<br />h3. Дізнайтесь більше
<br />table{border:1px solid lightgray}.<br />{background:lightgray }. |''. Про |''. Тут |<br />|Сигнали та слоти|'''&quot;Сигнали та слоти&amp;quot;:http://doc.qt.nokia.com/4.7/signalsandslots.html*|<br />|Компонування|'''&quot;Управління компонуванням&amp;quot;:http://doc.qt.nokia.com/4.7/layout.html''', '''&quot;Віджети та компонування&amp;quot;:http://doc.qt.nokia.com/4.7/widgets-and-layouts.html''', '''&quot;Приклади компонування&amp;quot;:http://doc.qt.nokia.com/4.7/examples-layouts.html'''|<br />|Віджети, що входять до Qt|'''&quot;Галерея віджетів Qt&amp;quot;:http://doc.qt.nokia.com/4.7/gallery.html''', '''&quot;Приклади віджетів&amp;quot;:http://doc.qt.nokia.com/4.7/examples-widgets.html'''|


== Успадкування від QWidget ==
== Успадкування від QWidget ==


Коли користувач бажає завершити програму, ви можете хотіти відобразити діалог, в якому запитаєте чи дійсно він хоче вийти. В цьому прикладі ми успадкуємось від &quot;QWidget&amp;quot;:http://doc.qt.nokia.com/4.7/qwidget.html та додамо слот, який під'єднаємо до '''кнопки Вихід'''.
Коли користувач бажає завершити програму, ви можете хотіти відобразити діалог, в якому запитаєте чи дійсно він хоче вийти. В цьому прикладі ми успадкуємось від [http://doc.qt.io/qt-4.8/qwidget.html QWidget] та додамо слот, який під'єднаємо до '''кнопки Вихід'''.


p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs3.png|http://doc.qt.nokia.com/4.7/images/gs3.png]]
[[Image:http://doc.qt.io/qt-4.8/images/gs3.png|http://doc.qt.io/qt-4.8/images/gs3.png]]


Давайте поглянемо на код:
Давайте поглянемо на код:


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


public:<br /> Notepad();
public:
Notepad();


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


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


Макрос &lt;code&amp;gt;Q_OBJECT&amp;lt;/code&amp;gt; повинен бути першим у визначенні класу, він оголошує наш клас як &lt;code&amp;gt;QObject&amp;lt;/code&amp;gt; (звичайно, він повинен бути успадкованим від &quot;QObject&amp;quot;:http://doc.qt.nokia.com/4.7/qobject.html). &quot;QObject&amp;quot;:http://doc.qt.nokia.com/4.7/qobject.html додає декілька особливостей до звичайного класу C++. Найважливішим є те, що назва класу та імена слотів можуть бути отримані під час виконання. Також є можливість дізнатись типи параметрів слоту та викликати його.
Макрос '''Q_OBJECT''' повинен бути першим у визначенні класу, він оголошує наш клас як '''QObject''' (звичайно, він повинен бути успадкованим від [http://doc.qt.io/qt-4.8/qobject.html QObject]). [http://doc.qt.io/qt-4.8/qobject.html QObject] додає декілька особливостей до звичайного класу C++. Найважливішим є те, що назва класу та імена слотів можуть бути отримані під час виконання. Також є можливість дізнатись типи параметрів слоту та викликати його.


В рядку 13 оголошено слот &lt;code&amp;gt;quit()&lt;/code&amp;gt;. Це легко зробити завдяки макросу &lt;code&amp;gt;slots&amp;lt;/code&amp;gt;. Слот &lt;code&amp;gt;quit()&lt;/code&amp;gt; тепер може бути під'єднаним до сигналів з відповідними сигнатурами (будь-який сигнал, що не приймає параметрів).
В рядку 13 оголошено слот '''quit()'''. Це легко зробити завдяки макросу '''slots'''. Слот '''quit()''' тепер може бути під'єднаним до сигналів з відповідними сигнатурами (будь-який сигнал, що не приймає параметрів).


Замість того, щоб встановлювати ГІК та під'єднувати слот в функції &lt;code&amp;gt;main()&lt;/code&amp;gt;, тепер ми використаємо конструктор &lt;code&amp;gt;Notepad&amp;lt;/code&amp;gt;.
Замість того, щоб встановлювати ГІК та під'єднувати слот в функції '''main()''', тепер ми використаємо конструктор '''Notepad'''.


<code><br />Notepad::Notepad()<br />{<br /> textEdit = new QTextEdit;<br /> quitButton = new QPushButton(tr(&quot;Quit&amp;quot;));
<code>
Notepad::Notepad()
{
textEdit = new QTextEdit;
quitButton = new QPushButton(tr("Quit"));


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


QVBoxLayout '''layout = new QVBoxLayout;<br /> layout-&gt;addWidget(textEdit);<br /> layout-&gt;addWidget(quitButton);
QVBoxLayout *layout = new QVBoxLayout;
<br /> setLayout(layout);
layout->addWidget(textEdit);
<br /> setWindowTitle(tr(&quot;Notepad&amp;quot;));<br />}<br /></code>
layout->addWidget(quitButton);
<br />p. Як видно у визначенні класу, ми використовуємо вказівники на наші &quot;QObject&amp;quot;:http://doc.qt.nokia.com/4.7/qobject.htmls'и (&lt;code&amp;gt;textEdit&amp;lt;/code&amp;gt; та &lt;code&amp;gt;quitButton&amp;lt;/code&amp;gt;). Як правило, вам завжди слід виділяти &quot;QObject&amp;quot;:http://doc.qt.nokia.com/4.7/qobject.htmls'и в купі та ніколи не копіювати їх.
 
<br />p. Тепер ми використовуємо функцію &quot;tr()&quot;:http://doc.qt.nokia.com/4.7/qobject.html#tr навколо рядків, що відображаються користувачу. Ця функція необхідна, якщо ви хочете надавати вашу програму більше ніж однією мовою (наприклад, англійською та китайською). Ми не будемо розглядати деталі тут, однак ви можете перейти за посиланням з таблиці &quot;Дізнайтесь більше&amp;quot; до &lt;code&amp;gt;Qt Linguist&amp;lt;/code&amp;gt;.
setLayout(layout);
<br />h3. Дізнайтесь більше  
 
<br />table{border:1px solid lightgray}.<br />{background:lightgray }. |''. Про |''. Тут |<br />|tr() та інтернаціоналізація|'''&quot;Посібник з Qt Linguist&amp;quot;:http://doc.qt.nokia.com/4.7/linguist-manual.html*, '''&quot;Написання коду для перекладу&amp;quot;:http://doc.qt.nokia.com/4.7/i18n-source-translation.html''', Приклад '''&quot;Привіт tr&amp;quot;:http://doc.qt.nokia.com/4.7/linguist-hellotr.html'''(), '''&quot;Інтернаціоналізація з Qt&amp;quot;:http://doc.qt.nokia.com/4.7/internationalization.html'''|<br />|&quot;QObject&amp;quot;:http://doc.qt.nokia.com/4.7/qtwebkit-bridge.html#qobjects'и та об'єктна модель Qt (Це необхідний матеріал, щоб зрозуміти Qt)|'''&quot;Об'єктна модель&amp;quot;:http://doc.qt.nokia.com/4.7/object.html'''|<br />|qmake та система збірки Qt|'''&quot;Посібник з qmake&amp;quot;:http://doc.qt.nokia.com/4.7/qmake-manual.html'''|
setWindowTitle(tr("Notepad"));
}
</code>
 
Як видно у визначенні класу, ми використовуємо вказівники на наші [http://doc.qt.io/qt-4.8/qobject.htmls'и QObject] ('''textEdit''' та '''quitButton'''). Як правило, вам завжди слід виділяти [http://doc.qt.io/qt-4.8/qobject.htmls'и QObject] в купі та ніколи не копіювати їх.
 
Тепер ми використовуємо функцію [http://doc.qt.io/qt-4.8/qobject.html#tr tr()] навколо рядків, що відображаються користувачу. Ця функція необхідна, якщо ви хочете надавати вашу програму більше ніж однією мовою (наприклад, англійською та китайською). Ми не будемо розглядати деталі тут, однак ви можете перейти за посиланням з таблиці "Дізнайтесь більше" до '''Qt Linguist'''.
 
=== Дізнайтесь більше ===
table{border:1px solid lightgray}.
{background:lightgray }. |''. Про |''. Тут |
|tr() та інтернаціоналізація|'''[http://doc.qt.io/qt-4.8/linguist-manual.html* Посібник з Qt Linguist], '''[http://doc.qt.io/qt-4.8/i18n-source-translation.html Написання коду для перекладу]''', Приклад '''[http://doc.qt.io/qt-4.8/linguist-hellotr.html Привіт tr]'''(), '''[http://doc.qt.io/qt-4.8/internationalization.html'''| Інтернаціоналізація з Qt]
|[http://doc.qt.io/qt-4.8/qtwebkit-bridge.html#qobjects'и QObject] та об'єктна модель Qt (Це необхідний матеріал, щоб зрозуміти Qt)|'''[http://doc.qt.io/qt-4.8/object.html'''| Об'єктна модель]
|qmake та система збірки Qt|'''[http://doc.qt.io/qt-4.8/qmake-manual.html'''| Посібник з qmake]


=== Створення файлу .pro ===
=== Створення файлу .pro ===


Для цього прикладу ми напишемо наш власний файл &lt;code&amp;gt;.pro&amp;lt;/code&amp;gt; замість використання &lt;code&amp;gt;qmake&amp;lt;/code&amp;gt; з опцією &lt;code&amp;gt;-project&amp;lt;/code&amp;gt;.
Для цього прикладу ми напишемо наш власний файл '''.pro''' замість використання '''qmake''' з опцією '''-project'''.


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


Наступні команди оболонки збирають приклад.
Наступні команди оболонки збирають приклад.


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


== Використання QMainWindow ==
== Використання QMainWindow ==


Багато програм отримають переваги від використання &quot;QMainWindow&amp;quot;:http://doc.qt.nokia.com/4.7/qmainwindow.html, який має своє власне компонування, до якого ви можете додавати панель меню, віджети, що прикріплюються, панелі інструментів та рядок статусу. &quot;QMainWindow&amp;quot;:http://doc.qt.nokia.com/4.7/qmainwindow.html має центральну область, що може бути зайнята віджетом довільного типу. В нашому випадку ми розташуємо там текстовий редактор.
Багато програм отримають переваги від використання [http://doc.qt.io/qt-4.8/qmainwindow.html QMainWindow], який має своє власне компонування, до якого ви можете додавати панель меню, віджети, що прикріплюються, панелі інструментів та рядок статусу. [http://doc.qt.io/qt-4.8/qmainwindow.html QMainWindow] має центральну область, що може бути зайнята віджетом довільного типу. В нашому випадку ми розташуємо там текстовий редактор.
 
[[Image:http://doc.qt.io/qt-4.8/images/gs4.png|http://doc.qt.io/qt-4.8/images/gs4.png]]


p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs4.png|http://doc.qt.nokia.com/4.7/images/gs4.png]]
Давайте поглянемо на нове визначення класу '''Notepad'''.


Давайте поглянемо на нове визначення класу &lt;code&amp;gt;Notepad&amp;lt;/code&amp;gt;.
<code>
#include <QtGui>
class Notepad : public QMainWindow
{
Q_OBJECT
public:
Notepad();
private slots:
void open();
void save();
void quit();
private:
QTextEdit *textEdit;
QAction *openAction;
QAction *saveAction;
QAction *exitAction;
QMenu *fileMenu;
};
</code>


<code><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 /></code>
Ми включили ще два слоти, які можуть зберігати та відкривати документ. Ми реалізуємо їх в наступній частині.
<br />p. Ми включили ще два слоти, які можуть зберігати та відкривати документ. Ми реалізуємо їх в наступній частині.
 
<br />p. Доволі часто в головному вікні один і той самий слот може бути викликаний декількома різними віджетами. Прикладами є пункти меню та кнопки на панелі інструментів. Щоб полегшити це, Qt надає &quot;QAction&amp;quot;:http://doc.qt.nokia.com/4.7/qaction.html (дія), який може бути переданий декільком віджетам та під'єднаний до слота. Наприклад, як &quot;QMenu&amp;quot;:http://doc.qt.nokia.com/4.7/qmenu.html так і &quot;QToolBar&amp;quot;:http://doc.qt.nokia.com/4.7/qtoolbar.html можуть створювати пункти меню та кнопки на панелі з одного й того ж &quot;QAction&amp;quot;:http://doc.qt.nokia.com/4.7/qaction.htmls. Ми скоро побачимо, як це працює.
Доволі часто в головному вікні один і той самий слот може бути викликаний декількома різними віджетами. Прикладами є пункти меню та кнопки на панелі інструментів. Щоб полегшити це, Qt надає [http://doc.qt.io/qt-4.8/qaction.html QAction] (дія), який може бути переданий декільком віджетам та під'єднаний до слота. Наприклад, як [http://doc.qt.io/qt-4.8/qmenu.html QMenu] так і [http://doc.qt.io/qt-4.8/qtoolbar.html QToolBar] можуть створювати пункти меню та кнопки на панелі з одного й того ж [http://doc.qt.io/qt-4.8/qaction.htmls QAction]. Ми скоро побачимо, як це працює.
<br />p. Як і раніше ми використовуємо конструктор &lt;code&amp;gt;Notepad&amp;lt;/code&amp;gt; для встановлення ГІК.
 
<br /><code><br />Notepad::Notepad()<br />{<br /> openAction = new QAction(tr(&quot;&amp;Open&amp;quot;), this);<br /> saveAction = new QAction(tr(&quot;&amp;Save&amp;quot;), this);<br /> exitAction = new QAction(tr(&quot;E&amp;amp;xit&amp;quot;), this);
Як і раніше ми використовуємо конструктор '''Notepad''' для встановлення ГІК.
<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;File&amp;quot;));<br /> fileMenu</s>&gt;addAction(openAction);<br /> fileMenu-&gt;addAction(saveAction);<br /> fileMenu-&gt;addSeparator();<br /> fileMenu-&gt;addAction(exitAction);
<code>
<br /> textEdit = new QTextEdit;<br /> setCentralWidget(textEdit);
Notepad::Notepad()
<br /> setWindowTitle(tr(&quot;Notepad&amp;quot;));<br />}<br /></code>
{
<br />p. &quot;QAction&amp;quot;:http://doc.qt.nokia.com/4.7/qaction.htmls'и створюються з текстом, що має з'явитись на віджетах, до яких ми їх додаємо (в нашому випадку це пункти меню). Якщо б ми також хотіли додати їх до панелі інструментів, ми б могли призначити до них &quot;піктограми&amp;quot;:http://doc.qt.nokia.com/4.7/qicon.html.
openAction = new QAction(tr("&Open"), this);
<br />p. Коли по пункту меню клацнуть, елемент запустить дію і буде викликано відповідний слот.
saveAction = new QAction(tr("&Save"), this);
<br />h3. Дізнайтесь більше
exitAction = new QAction(tr("E&xit"), this);
<br />table{border:1px solid lightgray}.<br />{background:lightgray }. |''. Про |''. Тут |<br />|Головні вікна та класи головного вікна||'''&quot;Головне вікно програми&amp;quot;:http://doc.qt.nokia.com/4.7/mainwindow.html*, '''&quot;Приклади головного вікна&amp;quot;:http://doc.qt.nokia.com/4.7/examples-mainwindow.html'''|<br />|Програми з MDI|'''&quot;QMdiArea&amp;quot;:http://doc.qt.nokia.com/4.7/qmdiarea.html''', '''&quot;Приклад MDI&amp;quot;:http://doc.qt.nokia.com/4.7/mainwindows-mdi.html'''|
 
connect(openAction, SIGNAL (triggered()), this, SLOT (open()));
connect(saveAction, SIGNAL (triggered()), this, SLOT (save()));
connect(exitAction, SIGNAL (triggered()), qApp, SLOT (quit()));
 
fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(openAction);
fileMenu->addAction(saveAction);
fileMenu->addSeparator();
fileMenu->addAction(exitAction);
 
textEdit = new QTextEdit;
setCentralWidget(textEdit);
 
setWindowTitle(tr("Notepad"));
}
</code>
 
[http://doc.qt.io/qt-4.8/qaction.htmls'и QAction] створюються з текстом, що має з'явитись на віджетах, до яких ми їх додаємо (в нашому випадку це пункти меню). Якщо б ми також хотіли додати їх до панелі інструментів, ми б могли призначити до них [http://doc.qt.io/qt-4.8/qicon.html піктограми].
 
Коли по пункту меню клацнуть, елемент запустить дію і буде викликано відповідний слот.
 
=== Дізнайтесь більше ===
table{border:1px solid lightgray}.
{background:lightgray }. |''. Про |''. Тут |
|Головні вікна та класи головного вікна||'''[http://doc.qt.io/qt-4.8/mainwindow.html* Головне вікно програми], '''[http://doc.qt.io/qt-4.8/examples-mainwindow.html'''| Приклади головного вікна]
|Програми з MDI|'''[http://doc.qt.io/qt-4.8/qmdiarea.html QMdiArea]''', '''[http://doc.qt.io/qt-4.8/mainwindows-mdi.html'''| Приклад MDI]


== Збереження та завантаження ==
== Збереження та завантаження ==


В цьому прикладі ми реалізуємо функціональність слотів &lt;code&amp;gt;open()&lt;/code&amp;gt; та &lt;code&amp;gt;save()&lt;/code&amp;gt;, які ми додали в попередньому прикладі.
В цьому прикладі ми реалізуємо функціональність слотів '''open()''' та '''save()''', які ми додали в попередньому прикладі.
 
[[Image:http://doc.qt.io/qt-4.8/images/gs5.png|http://doc.qt.io/qt-4.8/images/gs5.png]]
 
Ми почнемо зі слоту '''open()''':
 
<code>
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "",
tr("Text Files (*.txt);;C++ Files (*.cpp *.h)"));
 
if (fileName != "") {
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly)) {
QMessageBox::critical(this, tr("Error"),
tr("Could not open file"));
return;
}
QString contents = file.readAll().constData();
textEdit->setPlainText(contents);
file.close();
}
</code>
 
На першому кроці ми запитаємо у користувача ім'я файлу для відкриття. В Qt є [http://doc.qt.io/qt-4.8/qfiledialog.html QFileDialog] - діалог, з якого користувач може вибрати файл. На зображенні вище показано цей діалог в Kubuntu. Статична функція [http://doc.qt.io/qt-4.8/qfiledialog.html#getOpenFileName getOpenFileName()] відображує модальний файловий діалог, а повернення з неї не відбувається, доки користувач не вибере файл. Вона повертає шлях до обраного файлу або порожній рядок, якщо користувач скасував діалог.
 
Якщо в нас є ім'я файлу, ми намагаємось відкрити файл за допомогою функції [http://doc.qt.io/qt-4.8/qiodevice.html#open open()], яка повертає істинне значення, якщо файл вдалось відкрити. Ми не будемо тут заглиблюватись в обробку помилок, але ви можете перейти за посиланням з частини "Дізнайтесь більше". Якщо файл не вдалось відкрити, ми використовуємо [http://doc.qt.io/qt-4.8/qmessagebox.html QMessageBox], щоб відобразити діалог з повідомленням про помилку (див. опис класу [http://doc.qt.io/qt-4.8/qmessagebox.html QMessageBox] для деталей).


p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs5.png|http://doc.qt.nokia.com/4.7/images/gs5.png]]
Реальне читання даних є доволі тривіальним з використанням функції [http://doc.qt.io/qt-4.8/qiodevice.html#readAll readAll()], яка повертає усі дані з файлу в [http://doc.qt.io/qt-4.8/qbytearray.html QByteArray]. Метод [http://doc.qt.io/qt-4.8/qbytearray.html#constData constData()] повертає усі дані з масиву як const char*, для якого у [http://doc.qt.io/qt-4.8/qstring.html QString] є конструктор. Зміст в подальшому може бути відображено в текстовому редакторі. Потім ми закриваємо файл функцією [http://doc.qt.io/qt-4.8/qiodevice.html#close close()], щоб повернути файловий дескриптор назад операційній системі.


Ми почнемо зі слоту &lt;code&amp;gt;open()&lt;/code&amp;gt;:
Тепер, давайте перейдемо до слота '''save()'''.


<code><br />QString fileName = QFileDialog::getOpenFileName(this, tr(&quot;Open File&amp;quot;), &quot;&quot;,<br /> tr(&quot;Text Files ('''.txt);;C++ Files ('''.cpp '''.h)&quot;));
<code>
<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;Error&amp;quot;),<br /> tr(&quot;Could not open file&amp;quot;));<br /> return;<br /> }<br /> QString contents = file.readAll().constData();<br /> textEdit-&gt;setPlainText(contents);<br /> file.close();<br />}<br /></code>
QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "",
<br />p. На першому кроці ми запитаємо у користувача ім'я файлу для відкриття. В Qt є &quot;QFileDialog&amp;quot;:http://doc.qt.nokia.com/4.7/qfiledialog.html - діалог, з якого користувач може вибрати файл. На зображенні вище показано цей діалог в Kubuntu. Статична функція &quot;getOpenFileName()&quot;:http://doc.qt.nokia.com/4.7/qfiledialog.html#getOpenFileName відображує модальний файловий діалог, а повернення з неї не відбувається, доки користувач не вибере файл. Вона повертає шлях до обраного файлу або порожній рядок, якщо користувач скасував діалог.
tr("Text Files (*.txt);;C++ Files (*.cpp *.h)"));
<br />p. Якщо в нас є ім'я файлу, ми намагаємось відкрити файл за допомогою функції &quot;open()&quot;:http://doc.qt.nokia.com/4.7/qiodevice.html#open, яка повертає істинне значення, якщо файл вдалось відкрити. Ми не будемо тут заглиблюватись в обробку помилок, але ви можете перейти за посиланням з частини &quot;Дізнайтесь більше&amp;quot;. Якщо файл не вдалось відкрити, ми використовуємо &quot;QMessageBox&amp;quot;:http://doc.qt.nokia.com/4.7/qmessagebox.html, щоб відобразити діалог з повідомленням про помилку (див. опис класу &quot;QMessageBox&amp;quot;:http://doc.qt.nokia.com/4.7/qmessagebox.html для деталей).
<br />p. Реальне читання даних є доволі тривіальним з використанням функції &quot;readAll()&quot;:http://doc.qt.nokia.com/4.7/qiodevice.html#readAll, яка повертає усі дані з файлу в &quot;QByteArray&amp;quot;:http://doc.qt.nokia.com/4.7/qbytearray.html. Метод &quot;constData()&quot;:http://doc.qt.nokia.com/4.7/qbytearray.html#constData повертає усі дані з масиву як const char''', для якого у &quot;QString&amp;quot;:http://doc.qt.nokia.com/4.7/qstring.html є конструктор. Зміст в подальшому може бути відображено в текстовому редакторі. Потім ми закриваємо файл функцією &quot;close()&quot;:http://doc.qt.nokia.com/4.7/qiodevice.html#close, щоб повернути файловий дескриптор назад операційній системі.


Тепер, давайте перейдемо до слота &lt;code&amp;gt;save()&lt;/code&amp;gt;.
if (fileName != "") {
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly)) {
// повідомлення про помилку
} else {
QTextStream stream(&file);
stream << textEdit->toPlainText();
stream.flush();
file.close();
}
}
</code>


<code><br />QString fileName = QFileDialog::getSaveFileName(this, tr(&quot;Save File&amp;quot;), &quot;&quot;,<br /> tr(&quot;Text Files ('''.txt);;C++ Files ('''.cpp '''.h)&quot;));
Коли ми записуємо зміст текстового редактора до файлу, ми використовуємо клас [http://doc.qt.io/qt-4.8/qtextstream.html QTextStream], який обгортає об'єкт [http://doc.qt.io/qt-4.8/qfile.html QFile]. Текстовий потік може записувати QString'и безпосередньо до файлу; [http://doc.qt.io/qt-4.8/qfile.html QFile] приймає лише сирі дані (char*) за допомогою функцій [http://doc.qt.io/qt-4.8/qiodevice.html#write write()] класу [http://doc.qt.io/qt-4.8/qiodevice.html QIODevice].
<br />if (fileName != &quot;&quot;) {<br /> QFile file&amp;amp;#40;fileName&amp;amp;#41;;<br /> if (!file.open(QIODevice::WriteOnly)) {<br /> // повідомлення про помилку<br /> } else {<br /> QTextStream stream(&amp;file);<br /> stream &lt;&lt; textEdit-&gt;toPlainText();<br /> stream.flush();<br /> file.close();<br /> }<br />}<br /></code>
<br />p. Коли ми записуємо зміст текстового редактора до файлу, ми використовуємо клас &quot;QTextStream&amp;quot;:http://doc.qt.nokia.com/4.7/qtextstream.html, який обгортає об'єкт &quot;QFile&amp;quot;:http://doc.qt.nokia.com/4.7/qfile.html. Текстовий потік може записувати QString'и безпосередньо до файлу; &quot;QFile&amp;quot;:http://doc.qt.nokia.com/4.7/qfile.html приймає лише сирі дані (char''') за допомогою функцій &quot;write()&quot;:http://doc.qt.nokia.com/4.7/qiodevice.html#write класу &quot;QIODevice&amp;quot;:http://doc.qt.nokia.com/4.7/qiodevice.html.


=== Дізнайтесь більше ===
=== Дізнайтесь більше ===


table{border:1px solid lightgray}.<br />{background:lightgray }. |''. Про |''. Тут |<br />|Файли та пристрої I/O|'''&quot;QFile&amp;quot;:http://doc.qt.nokia.com/4.7/qfile.html''', '''&quot;QIODevice&amp;quot;:http://doc.qt.nokia.com/4.7/qiodevice.html'''|
table{border:1px solid lightgray}.
{background:lightgray }. |''. Про |''. Тут |
|Файли та пристрої I/O|'''[http://doc.qt.io/qt-4.8/qfile.html QFile]''', '''[http://doc.qt.io/qt-4.8/qiodevice.html'''| QIODevice]

Latest revision as of 10:18, 27 February 2017

This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine.
Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean.


Перші кроки з Qt

Ласкаво просимо до світу Qt — крос-платформного набору інструментів для ГІК (графічного інтерфейсу користувача). В цьому посібнику з перших кроків ми отримаємо базові знання з Qt, реалізовуючи просту програму Нотатник. Після прочитання цього посібника ви маєте бути готові зануритись до наших оглядів та документації з API та знайти потрібну вам інформацію для програми, що ви розробляєте.

Привіт, Нотатник

В цьому першому прикладі ми просто створимо та відобразимо текстовий редактор у вікні на стільниці. Це буде найпростіша можлива програма Qt, що має ГІК.

http://doc.qt.io/qt-4.8/images/gs1.png

Код програми:

#include <QApplication>
#include <QTextEdit>

int main(int argc, char **argv)
{
 QApplication app(argc, argv);

 QTextEdit textEdit;
 textEdit.show();

 return app.exec();
}

Давайте переглянемо код рядок за рядком. В перших двох рядках ми підключаємо файли заголовків для QApplication та QTextEdit, двох класів, що потрібні для цього прикладу. Усі класи Qt мають файл заголовків, названий так само як і клас.

В рядку 6 створюється об'єкт QApplication. Цей об'єкт керує ресурсами програми і має бути запущений в будь-який програмі Qt, що має ГІК. Йому передаються argc та argv, оскільки Qt обробляє деякі параметри командного рядка.

В рядку 8 створюється об'єкт QTextEdit. Текстовий редактор є візуальним елементом ГІК. Ми називаємо такі елементи віджетами в Qt. Прикладами інших віджетів є панелі прокрутки, мітки та перемикачі. Віджет також може бути контейнером для інших віджетів, як, наприклад, діалог або головне вікно програми.

В рядку 9 текстовий редактор відображується на екрані у його власному вікні. Оскільки віджети також функціонують як контейнери (наприклад, QMainWindow, який має панелі інструментів, меню, рядок статусу та декілька інших віджетів), то можна відобразити один віджет у його власному вікні. Віджети не відображаються за замовчанням; функція show() робить віджет видимим.

В рядку 11 відбувається вхід до циклу подій QApplication. Коли програма Qt виконується, генеруються події, що доставляються до віджетів програми. Прикладами подій є натискання на кнопки миші та клавіші клавіатури. Коли ви набираєте текст в віджеті текстового редактора, він отримує події натискання клавіш та реагує промальовуванням тексту, що набирається.

Щоб запустити програму, відкрийте командний рядок та перейдіть до теки, в якій знаходиться файл .cpp програми. Наступні команди оболонки зберуть програму.

qmake -project
qmake
make

При цьому виконуваний модуль з'явиться в теці part1 (майте на увазі, що у Windows вам, можливо, потрібно буде використовувати nmake замість make. Також, виконуваний модуль буде розміщено в part1/debug або part1/release). qmake - це інструмент збірки з Qt, який використовує конфігураційний файл. qmake генерує його для нас, коли запускається з аргументом -project. Коли конфігураційний файл (із суфіксом .pro) існує, qmake створює файл збірки, який збирає для вас програму. Ми розглянемо написання власних файлів .pro пізніше.

Дізнайтесь більше

table{border:1px solid lightgray}. {background:lightgray }. |. Про |. Тут | |Віджети та геометрія вікна|| Віджети вікна та діалогу |Події та обробка подій|| Система подій

Додаємо кнопку виходу

В справжній програмі вам, зазвичай, буде потрібен більше ніж один віджет. Зараз ми додамо QPushButton нижче текстового редактора. Кнопка буде здійснювати вихід з програми Нотатник, коли на неї будуть натискати (наприклад, клацнуть мишею).

http://doc.qt.io/qt-4.8/images/gs2.png

Давайте поглянемо на код.

#include <QtGui>

int main(int argv, char **args)
{
 QApplication app(argv, args);

 QTextEdit textEdit;
 QPushButton quitButton("Quit");

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

 QVBoxLayout layout;
 layout.addWidget(&textEdit);
 layout.addWidget(&quitButton);

 QWidget window;
 window.setLayout(&layout);

 window.show();

 return app.exec();
}

Рядок 1 включає QtGui, який містить усі класи ГІК Qt.

В рядку 10 використовується механізм сигналів та слотів Qt, щоб завершити програму, коли натискається кнопка Вихід. Слот- це функція, що може бути викликана під час виконання програми за допомогою її назви (як рядкового літералу). Сигналом є функція, яка під час свого виклику, виконає слоти зареєстровані до неї; ми називаємо це "під'єднати слот до сигналу та видати сигнал".

quit() є слотом QApplication, який завершує програму. clicked() є сигналом, який QPushButton видає, коли натискається. Статична функція QObject::connect() піклується про з'єднання слота із сигналом. SIGNAL() та SLOT() - це два макроси, що приймають сигнатури функцій сигналу та слота, що з'єднуються. Також ми повинні передати вказівники на об'єкти, що мають надіслати та отримати сигнал.

В рядку 12 створюється QVBoxLayout. Як вже згадувалось, віджети можуть містити інші віджети. Можна встановити границі (розташування та розмір) дочірніх віджетів безпосередньо, однак, зазвичай легше використати компонувальник. Компонувальник керує границями дочірніх віджетів. Наприклад, QVBoxLayout розташовує дітей у вертикальному рядку.

Рядки 13 та 14 додають текстовий редактор до компонувальника. В рядку 17 ми встановлюємо конмпонувальник на віджет.

Дізнайтесь більше

table{border:1px solid lightgray}. {background:lightgray }. |. Про |. Тут | |Сигнали та слоти|Сигнали та слоти |Компонування|Управління компонуванням, Віджети та компонування, | Приклади компонування |Віджети, що входять до Qt|Галерея віджетів Qt, | Приклади віджетів

Успадкування від QWidget

Коли користувач бажає завершити програму, ви можете хотіти відобразити діалог, в якому запитаєте чи дійсно він хоче вийти. В цьому прикладі ми успадкуємось від QWidget та додамо слот, який під'єднаємо до кнопки Вихід.

http://doc.qt.io/qt-4.8/images/gs3.png

Давайте поглянемо на код:

class Notepad : public QWidget
{
 Q_OBJECT

public:
 Notepad();

private slots:
 void quit();

private:
 QTextEdit *textEdit;
 QPushButton *quitButton;
};

Макрос Q_OBJECT повинен бути першим у визначенні класу, він оголошує наш клас як QObject (звичайно, він повинен бути успадкованим від QObject). QObject додає декілька особливостей до звичайного класу C++. Найважливішим є те, що назва класу та імена слотів можуть бути отримані під час виконання. Також є можливість дізнатись типи параметрів слоту та викликати його.

В рядку 13 оголошено слот quit(). Це легко зробити завдяки макросу slots. Слот quit() тепер може бути під'єднаним до сигналів з відповідними сигнатурами (будь-який сигнал, що не приймає параметрів).

Замість того, щоб встановлювати ГІК та під'єднувати слот в функції main(), тепер ми використаємо конструктор Notepad.

Notepad::Notepad()
{
 textEdit = new QTextEdit;
 quitButton = new QPushButton(tr("Quit"));

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

QVBoxLayout *layout = new QVBoxLayout;
 layout->addWidget(textEdit);
 layout->addWidget(quitButton);

 setLayout(layout);

 setWindowTitle(tr("Notepad"));
}

Як видно у визначенні класу, ми використовуємо вказівники на наші QObject (textEdit та quitButton). Як правило, вам завжди слід виділяти QObject в купі та ніколи не копіювати їх.

Тепер ми використовуємо функцію tr() навколо рядків, що відображаються користувачу. Ця функція необхідна, якщо ви хочете надавати вашу програму більше ніж однією мовою (наприклад, англійською та китайською). Ми не будемо розглядати деталі тут, однак ви можете перейти за посиланням з таблиці "Дізнайтесь більше" до Qt Linguist.

Дізнайтесь більше

table{border:1px solid lightgray}. {background:lightgray }. |. Про |. Тут | |tr() та інтернаціоналізація|Посібник з Qt Linguist, Написання коду для перекладу, Приклад Привіт tr(), | Інтернаціоналізація з Qt |QObject та об'єктна модель Qt (Це необхідний матеріал, щоб зрозуміти Qt)|| Об'єктна модель |qmake та система збірки Qt|| Посібник з qmake

Створення файлу .pro

Для цього прикладу ми напишемо наш власний файл .pro замість використання qmake з опцією -project.

HEADERS = notepad.h
SOURCES = notepad.cpp  main.cpp

Наступні команди оболонки збирають приклад.

qmake
make

Використання QMainWindow

Багато програм отримають переваги від використання QMainWindow, який має своє власне компонування, до якого ви можете додавати панель меню, віджети, що прикріплюються, панелі інструментів та рядок статусу. QMainWindow має центральну область, що може бути зайнята віджетом довільного типу. В нашому випадку ми розташуємо там текстовий редактор.

http://doc.qt.io/qt-4.8/images/gs4.png

Давайте поглянемо на нове визначення класу Notepad.

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

Ми включили ще два слоти, які можуть зберігати та відкривати документ. Ми реалізуємо їх в наступній частині.

Доволі часто в головному вікні один і той самий слот може бути викликаний декількома різними віджетами. Прикладами є пункти меню та кнопки на панелі інструментів. Щоб полегшити це, Qt надає QAction (дія), який може бути переданий декільком віджетам та під'єднаний до слота. Наприклад, як QMenu так і QToolBar можуть створювати пункти меню та кнопки на панелі з одного й того ж QAction. Ми скоро побачимо, як це працює.

Як і раніше ми використовуємо конструктор Notepad для встановлення ГІК.

Notepad::Notepad()
{
 openAction = new QAction(tr("&Open"), this);
 saveAction = new QAction(tr("&Save"), this);
 exitAction = new QAction(tr("E&xit"), this);

 connect(openAction, SIGNAL (triggered()), this, SLOT (open()));
 connect(saveAction, SIGNAL (triggered()), this, SLOT (save()));
 connect(exitAction, SIGNAL (triggered()), qApp, SLOT (quit()));

 fileMenu = menuBar()->addMenu(tr("&File"));
 fileMenu->addAction(openAction);
 fileMenu->addAction(saveAction);
 fileMenu->addSeparator();
 fileMenu->addAction(exitAction);

 textEdit = new QTextEdit;
 setCentralWidget(textEdit);

 setWindowTitle(tr("Notepad"));
}

QAction створюються з текстом, що має з'явитись на віджетах, до яких ми їх додаємо (в нашому випадку це пункти меню). Якщо б ми також хотіли додати їх до панелі інструментів, ми б могли призначити до них піктограми.

Коли по пункту меню клацнуть, елемент запустить дію і буде викликано відповідний слот.

Дізнайтесь більше

table{border:1px solid lightgray}. {background:lightgray }. |. Про |. Тут | |Головні вікна та класи головного вікна||Головне вікно програми, | Приклади головного вікна |Програми з MDI|QMdiArea, | Приклад MDI

Збереження та завантаження

В цьому прикладі ми реалізуємо функціональність слотів open() та save(), які ми додали в попередньому прикладі.

http://doc.qt.io/qt-4.8/images/gs5.png

Ми почнемо зі слоту open():

QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "",
 tr("Text Files (*.txt);;C++ Files (*.cpp *.h)"));

if (fileName != "") {
 QFile file(fileName);
 if (!file.open(QIODevice::ReadOnly)) {
 QMessageBox::critical(this, tr("Error"),
 tr("Could not open file"));
 return;
 }
 QString contents = file.readAll().constData();
 textEdit->setPlainText(contents);
 file.close();
}

На першому кроці ми запитаємо у користувача ім'я файлу для відкриття. В Qt є QFileDialog - діалог, з якого користувач може вибрати файл. На зображенні вище показано цей діалог в Kubuntu. Статична функція getOpenFileName() відображує модальний файловий діалог, а повернення з неї не відбувається, доки користувач не вибере файл. Вона повертає шлях до обраного файлу або порожній рядок, якщо користувач скасував діалог.

Якщо в нас є ім'я файлу, ми намагаємось відкрити файл за допомогою функції open(), яка повертає істинне значення, якщо файл вдалось відкрити. Ми не будемо тут заглиблюватись в обробку помилок, але ви можете перейти за посиланням з частини "Дізнайтесь більше". Якщо файл не вдалось відкрити, ми використовуємо QMessageBox, щоб відобразити діалог з повідомленням про помилку (див. опис класу QMessageBox для деталей).

Реальне читання даних є доволі тривіальним з використанням функції readAll(), яка повертає усі дані з файлу в QByteArray. Метод constData() повертає усі дані з масиву як const char*, для якого у QString є конструктор. Зміст в подальшому може бути відображено в текстовому редакторі. Потім ми закриваємо файл функцією close(), щоб повернути файловий дескриптор назад операційній системі.

Тепер, давайте перейдемо до слота save().

QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "",
 tr("Text Files (*.txt);;C++ Files (*.cpp *.h)"));

if (fileName != "") {
 QFile file(fileName);
 if (!file.open(QIODevice::WriteOnly)) {
 // повідомлення про помилку
 } else {
 QTextStream stream(&file);
 stream << textEdit->toPlainText();
 stream.flush();
 file.close();
 }
}

Коли ми записуємо зміст текстового редактора до файлу, ми використовуємо клас QTextStream, який обгортає об'єкт QFile. Текстовий потік може записувати QString'и безпосередньо до файлу; QFile приймає лише сирі дані (char*) за допомогою функцій write() класу QIODevice.

Дізнайтесь більше

table{border:1px solid lightgray}. {background:lightgray }. |. Про |. Тут | |Файли та пристрої I/O|QFile, | QIODevice