Qt:Документация 4.3.2/tutorial-t7
Материал из Wiki.crossplatform.ru
Внимание: Актуальная версия перевода документации находится здесь |
__NOTOC__
Главная · Все классы · Основные классы · Классы по группам · Модули · Функции |
[Предыдущая: Часть 6 ] [ Учебное руководство ] [Следующая: Часть 8 ]
Содержание |
[править] Урок 7 - Влияние одного объекта на другие
Файлы:
Этот пример показывает, как связывать с помощью слотов и сигналов создаваемые вами виджеты в более сложных случаях. В этом примере мы разнесели наш код в несколько файлов, которые мы поместили в каталог examples/tutorial/t7.
[править] Строчка за строчкой
[править] t7/lcdrange.h
Содержимое этого файла мы фактически взяли из main.cpp шестой части. Рассмотрим только его отличия.
#ifndef LCDRANGE_H #define LCDRANGE_H
Эти строчки вместе с #endif в конце файла являются стандартной конструкцией языка С++, позволяющей избежать ошибок, если вы пытаетесь подключить заголовочный файл несколько раз. Если в своих программах вы еще не использовали эту конструкцию, то мы настоятельно рекомендуем начать это делать.
#include <QWidget>
Подключаем класс <QWidget>, так как наш LCDRange будет наследовать QWidget. Заголовочный файл родительского класса необходимо всегда подключать - мы немного хитрили в предыдущих частях, не подключая <QWidget> явно, а через другие заголовочные файлы.
class QSlider;
Это ещё один трюк с классами, он используется несколько реже. Так как мы не нуждаемся в полном интерфейсе класса QSlider, мы используем вышеописанную декларацию в этом заголовочном файле, а подключаем полное описание QSlider в файле .cpp.
Использовании данной конструкции позволит сократить время компиляции больших программ, так как при этом компилятор тратит очень много времени на анализ заголовочных файлов. Этот приём может позволить сократить время компиляции в два-три раза.
class LCDRange : public QWidget { Q_OBJECT public: LCDRange(QWidget *parent = 0);
Обратите внимание на Q_OBJECT. Этот макрос должен быть включён во все классы, которые используют сигналы или слоты. Если вам интересно, он определяет функции, включённые в мета-объектном файл.
int value() const; public slots: void setValue(int value); signals: void valueChanged(int newValue);
Эти три свойства класса являются интерфейсом для взаимодействия с другими компонентами в нашей программе. В предыдущих главах LCDRange не имел своего API.
value() - публичная функция, возвращающая значение LCDRange, setValue() - создаваемый нами слот, valueChanged() - создаваемый нами сигнал.
Слоты должны быть реализованы обычным способом (слот является членом С++ класса). Сигналы автоматически обрабатываются в мета-объектном файле. Сигналы должны быть описаны как защищенные (protected) функции (то есть они могут запускаться только непосредственно самим классом или его потомком).
Сигнал valueChanged() вызывается только тогда, когда изменилось значение LCDRange.
[править] t7/lcdrange.cpp
Содержимое этого файла мы также фактически взяли из main.cpp шестой части. Рассмотрим его отличия.
connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int))); connect(slider, SIGNAL(valueChanged(int)), this, SIGNAL(valueChanged(int)));
Этот код взят из конструктора LCDRange.
Первый вызов функции connect()ничем не отличается от примера, приведенного в предыдущей главе. Второй вызов новый для нас: мы подключаем сигнал valueChanged() слайдера к сигналу valueChanged(). Да, это так. Сигналы могут быть связаны. При возникновении первого сигнала, второй также вызывается.
Давайте разберем что происходит, когда пользователь управляет слайдером. Слайдер принимает сигнал об изменении своего значения valueChanged(). Запускаемый сигнал связан со слотом display()объекта QLCDNumber и с сигналом valueChanged() объекта LCDRange.
Таким образом, когда сигнал посылается, LCDRange посылает свой сигнал valueChanged(). Кроме того, вызывается QLCDNumber::display() и показывает новое значение.
Заметьте, что вам не даётся гарантия очерёдности обработки сигнала; LCDRange::valueChanged() может вызваться до или после QLCDNumber::display().
int LCDRange::value() const { return slider->value(); }
Вызов value() осуществляется на прямую. Этот метод посто возвращает значение слайдера.
void LCDRange::setValue(int value) { slider->setValue(value); }
Вызов setValue() также осуществляется напрямую. Заметьте, что значение слайдера и LCD монитора связаны между собой, и, устанавливая новое значение слайдера, вы автоматически меняете значение на экране LCD монитора. Кроме того, слайдер автоматически корректирует значение, если оно было задано вне его пределов.
[править] t7/main.cpp
LCDRange *previousRange = 0; for (int row = 0; row < 3; ++row) { for (int column = 0; column < 3; ++column) { LCDRange *lcdRange = new LCDRange; grid->addWidget(lcdRange, row, column); if (previousRange) connect(lcdRange, SIGNAL(valueChanged(int)), previousRange, SLOT(setValue(int))); previousRange = lcdRange; } }
Большая часть main.cppиз предыдущей главы, отличия заключаются в вызове конструктора MyWidget. Мы создаем девять объектов LCDRange, а также соединяем их, спользуя механизм сигалов и слотов. Каждый объект (кроме первого) посылает сигнал valueChanged() при изменения значения в слот setValue() предыдущего. Так как LCDRange посылает сигнал valueChanged(), когда изменяется значение, получается цепочка сигналов и слотов.
[править] Компиляция приложения
Создание make-файла для этой программы не отличается от такового в предыдущих главах, где все приложение было в одном файле. Просто сохраните все файлы в одном каталоге и выполните следующие действия:
qmake -project
qmake
Первой командой qmake мы создаем проектный файл (.pro файл). Следующей командой мы создаем make-файл (он является платформозависимым), основанный на проектном файле. Теперь вы можете выполнить команду make (или nmake, если вы используете Visual Studio), и вы получите своё приложение.
[править] Запуск приложения
Это приложение анологично программе, созданной нами в предыдущей главе. Попробуйте подвигать нижний правый слайдер.
[править] Домашнее задание
Используйте правый нижний слайдер для установки значения 50 на всех LCD. Затем установите верхние 6 в значение 30, кликая по слайдеру на строке выше. Теперь, используйте левый от этого, для установки значения 50 на первых пяти LCD.
Кликните слева от ползунка правого-нижнего слайдера. Что получится? Почему такое поведение правильное?
[Предыдущая: Часть 6 ] [ Учебное руководство ] [Следующая: Часть 8 ]
Copyright © 2007 Trolltech | Trademarks | Qt 4.3.2
|