- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания QT 4 программирование GUI на С++ Жасмин Бланшет
Шрифт:
Интервал:
Закладка:
11 connect(wmp, SIGNAL(PositionChange(double, double)),
12 this, SLOT(onPositionChange(double, double)));
После вызова QAxWidget::setControl() мы вызываем функцию QObject::setProperty() для установки свойства ShowControls (отображать элементы управления) элемента управления Media Player системы Windows на значение false, поскольку мы предоставляем свои собственные кнопки для работы с компонентом. Функция QObject::setProperty() может использоваться как для свойств СОМ, так и для обычных свойств Qt. Ее второй параметр имеет тип QVariant.
Затем мы вызываем функцию setSizePolicy(), чтобы элемент управления ActiveX мог занять все имеющееся в менеджере компоновки пространство, и мы подсоединяем три события ActiveX компонента СОМ к трем слотам.
13 stopButton = new QToolButton;
14 stopButton->setText(tr("&Stop"));
15 stopButton->setEnabled(false);
16 connect(stopButton, SIGNAL(clicked()), wmp, SLOT(Stop()));
17 …
18 }
Остальная часть конструктора PlayerWindow следует обычному образцу, за исключением того, что мы подсоединяем некоторые сигналы Qt к слотам объекта COM (Play(), Pause() и Stop()). Мы показали здесь реализацию только кнопки Stop, поскольку другие кнопки реализуются аналогично.
01 void PlayerWindow::timerEvent(QTimerEvent *event)
02 {
03 if (event->timerId() == updateTimer) {
04 double curPos = wmp->property("CurrentPosition").toDouble();
05 onPositionChange(-1, curPos);
06 } else {
07 QWidget::timerEvent(event);
08 }
09 }
Функция timerEvent() вызывается через определенные интервалы времени во время проигрывания мультимедийного клипа. Мы используем ее для продвижения ползунка. Это делается путем вызова функции property() для элемента управления ActiveX, чтобы получить значение свойства CurrentPosition (текущая позиция) в виде объекта типа QVariant и вызова функции toDouble() для преобразования его в тип double. Мы затем вызываем функцию onPositionChange() для обновления положения ползунка.
Мы не будем рассматривать остальную часть программного кода, поскольку большая часть его не имеет непосредственного отношения к ActiveX и не содержит ничего такого, что мы уже не обсуждали ранее. Данный программный код имеется на компакт-диске.
В файле .pro нам необходимо задать элемент для связи с модулем QAxContainer.
CONFIG += qaxcontainer
При работе с объектами СОМ одной из часто возникающих потребностей является необходимость непосредственного вызова метода СОМ (вместо подсоединения его к сигналу Qt). Наиболее просто это сделать путем вызова функции QAxBase::dynamicCall() с указанием имени и сигнатуры метода в первом параметре и аргументов метода в дополнительных параметрах. Например:
wmp->dynamicCall("TitlePlay(uint)", 6);
Функция dynamicCall() принимает до восьми параметров типа QVariant и возвращает объект типа QVariant. Если нам необходимо передавать таким образом IDispatch * или IUnknown *, мы можем инкапсулировать компонент в QAxObject и вызвать для него функцию asVariant() для преобразования его в тип QVariant. Если нам необходимо вызвать метод СОМ, который возвращает IDispatch * или IUnknown *, или если нам необходимо осуществлять доступ к свойству СОМ одного из этих типов, мы можем вместо этого использовать функцию querySubObject():
QAxObject *session = outlook.querySubObject('"Session");
QAxObject *defaultContacts =
session->querySubObject("GetDefaultFolder(01DefaultFolders)",
"olFolderContacts");
Если мы собираемся вызывать методы, которые имеют неподдерживаемые типы данных в их списке параметров, мы можем использовать QAxBase::queryInterface() для получения интерфейса СОМ и непосредственного вызова метода. Мы должны вызвать функцию Release() после завершения использования интерфейса, что является обычным при работе с СОМ. Если нам приходится часто вызывать такие методы, мы можем создать подкласс QAxObject или QAxWidget и обеспечить функции—члены, которые инкапсулируют вызовы интерфейса СОМ. Однако убедитесь, что подклассы QAxObject и QAxWidget не могут определять свои собственные свойства, сигналы и слоты.
Теперь мы рассмотрим модуль QAxServer. Этот модуль позволяет нам превратить стандартную программу Qt в сервер ActiveX. Сервер может быть как совместно используемой библиотекой, так и автономным приложением. Серверы в виде совместно используемых библиотек часто называют внутрипроцессными серверами (in-process servers), а автономные приложения — внепроцессными серверами (out-of-process servers).
Наш первый пример QAxServer является внутрипроцессным сервером, отображающим виджет с шариком, который может прыгать вправо и влево. Мы рассмотрим также способы встраивания этого виджета в Internet Explorer.
Рис. 20.6. Виджет AxBouncer в Internet Explorer.
Ниже приводится начало определения класса виджета AxBouncer:
01 class AxBouncer : public QWidget, public QAxBindable
02 {
03 Q_OBJECT
04 Q_ENUMS(SpeedValue)
05 Q_PROPERTY(QColor color READ color WRITE setColor)
06 Q_PROPERTY(SpeedValue speed READ speed WRITE setSpeed)
07 Q_PROPERTY(int radius READ radius WRITE setRadius)
08 Q_PROPERTY(bool running READ isRunning)
AxBouncer наследует как QWidget, так и QAxBindable. Класс QAxBindable обеспечивает интерфейс между виджетом и клиентом ActiveX. Любой QWidget может быть экспортирован как элемент управления ActiveX, но путем создания подкласса QAxBindable мы можем уведомлять клиента об изменениях значения свойства и peализовывать интерфейсы СОМ в дополнение к уже реализованным при помощи QAxServer.
Если при использовании множественного наследования имеются классы, производные от QObject, мы должны всегда располагать производные от QObject классы первыми для того, чтобы компилятор moc мог их извлечь.
Мы объявляем три свойства для чтения и записи и одно свойство только для чтения. Макрос Q_ENUMS() необходим для указания компилятору moc на то, что SpeedValue имеет тип enum (перечисление). Это перечисление объявляется в открытой секции класса:
09 public:
10 enum SpeedValue { Slow, Normal, Fast };
11 AxBouncer(QWidget *parent = 0);
12 void setSpeed(SpeedValue newSpeed);
13 SpeedValue speed() const { return ballSpeed; }
14 void setRadius(int newRadius);
15 int radius() const { return ballRadius; }
16 void setColor(const QColor &newColor);
17 QColor color() const { return ballColor; }
18 bool isRunning() const { return myTimerId != 0; }
19 QSize sizeHint() const;
20 QAxAggregated *createAggregate();
21 public slots:
22 void start();
23 void stop();
24 signals:
25 void bouncing();
Конструктор AxBouncer является стандартным конструктором виджета с параметром parent. Макрос QAXFACTORY_DEFAULT(), который мы используем для экспорта компонента, предполагает, что у конструктора именно такая сигнатура.
Функция createAggregate() класса QAxBindable переопределяется. Мы рассмотрим ее вскоре.
26 protected:
27 void paintEvent(QPaintEvent *event);
28 void timerEvent(QTimerEvent *event);
29 private:
30 int intervalInMilliseconds() const;
31 QColor ballColor;
32 SpeedValue ballSpeed;
33 int ballRadius;
34 int myTimerId;
35 int x;
36 int delta;
37 };
Защищенная и закрытая секции этого класса имеют тот же вид, как и для стандартного виджета Qt.
01 AxBouncer::AxBouncer(QWidget *parent)
02 : QWidget(parent)
03 {
04 ballColor = Qt::blue;
05 ballSpeed = Normal;
06 ballRadius = 15;
07 myTimerId = 0;
08 x = 20;
09 delta = 2;
10 }
Конструктор AxBouncer инициализирует закрытые переменные этого класса.
01 void AxBouncer::setColor(const QColor &newColor)
02 {
03 if (newColor != ballColor &&
04 requestPropertyChange("color")) {
05 ballColor = newColor;
06 update();
07 propertyChanged("color");
08 }
09 }
Функция setColor() устанавливает значение свойства color (цвет). Она вызывает функцию update() для перерисовки виджета.
Необычной частью являются вызовы функций requestPropertyChange() и propertyChanged(). Эти функции наследуются от класса QAxBindable и в идеальном случае должны вызываться при всяком изменении свойства. Функция requestPropertyChange() спрашивает у клиента разрешение на изменение свойства и возвращает true, если клиент дает такое разрешение. Функция propertyChanged() уведомляет клиента о том, что свойство изменилось.