Жасмин Бланшет - QT 4: программирование GUI на С++
- Название:QT 4: программирование GUI на С++
- Автор:
- Жанр:
- Издательство:КУДИЦ-ПРЕСС
- Год:2007
- Город:Москва
- ISBN:978-5-91136-038-2
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Жасмин Бланшет - QT 4: программирование GUI на С++ краткое содержание
Единственное официальное руководстро по практическому программированию в среде Qt 4.1.
Применяя средства разработки Qt компании «Trolltech», вы сможете создавать на С++ промышленные приложения, которые естественно работают в средах Windows, Linux/UNIX, Linux для встроенных систем без изменения программного кода и Mac Os X. Книга написана сотрудниками компании «Trolltech». Она представляет собой практическое руководство по успешному применению самой мощной из всех созданных до сих пор версий Qt — Qt 4.1.
Из книги «Qt 4: программирование GUI на С++» вы узнаете о наиболее эффективных приемах и методах программирования с применением Qt 4 и овладеете ключевыми технологиями в самых различных областях — от архитектуры Qt модель/представление до мощного графического процессора 2D. Авторы вооружают читателей беспрецедентно глубокими знаниями модели событий и системы компоновки Qt.
На реалистических примерах они описывают высокоэффективные методы во всех областях — от разработки основных элементов графического пользовательского интерфейса до передовых методов интеграции с базой данных и XML. Каждая глава содержит полностью обновленный материал.
Данное издание:
• Включает новые главы по архитектуре Qt 4 модель/представление и поддержке подключаемых модулей Qt, а также краткое введение в программирование встроенных систем на платформе Qtopia.
• Раскрывает все основные принципы программирования в среде Qt — от создания диалоговых и других окон до реализации функциональности приложений.
• Знакомит с передовыми методами управления компоновкой виджетов и обработкой событий.
• Показывает, как можно с наибольшей эффективностью использовать новые программные интерфейсы Qt 4, в частности мощный графический процессор 2D и новые простые в применении классы—контейнеры.
• Представляет передовые методы Qt 4, которых нет ни в одной книге: от создания подключаемых модулей, расширяющих возможности Qt, и приложений, до применения «родных» для конкретной платформы программных интерфейсов.
• Содержит приложение с подробным введением в программирование на С++ в среде Qt для опытных Java—разработчиков.
Жасмин Бланшет (Jasmine Blanchette) — менеджер по документированию и старший разработчик компании «Trolltech» с 2001 года. Он является редактором «Qt Quarterly», информационного бюллетеня компании «Trolltech», и соавтором книги «Qt 3: программирование GUI на С++».
Марк Саммерфилд (Mark Summerfield) — независимый преподаватель и консультант по С++, Qt и Python. Он работал менеджером по документированию в компании «Trolltech» на протяжении трех лет. Марк является соавтором книги «Qt 3: программирование GUI на С++».
QT 4: программирование GUI на С++ - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
14 this, SLOT(allTransactionsDone()));
15 setCurrentFile("");
16 }
Интересной частью конструктора ImageWindow являются два соединения сигнал—слот. В обоих случаях сигнал генерируется объектом TransactionThread, который мы вскоре рассмотрим.
01 void ImageWindow::flipHorizontally()
02 {
03 addTransaction(new FlipTransaction(Qt::Horizontal));
04 }
Слот flipHorizontally() создает транзакцию зеркального отражения и регистрирует ее при помощи закрытой функции addTransaction(). Функции flipVertically(), resizeImage(), convertTo32Bit(), convertTo8Bit() и convertTo1Bit() реализуются аналогично.
01 void ImageWindow::addTransaction(Transaction *transact)
02 {
03 thread.addTransaction(transact);
04 openAction->setEnabled(false);
05 saveAction->setEnabled(false);
06 saveAsAction->setEnabled(false);
07 }
Функция addTransaction() добавляет транзакцию в очередь транзакций вторичного потока и отключает команды Open, Save и Save As на время обработки транзакций.
01 void ImageWindow::allTransactionsDone()
02 {
03 openAction->setEnabled(true);
04 saveAction->setEnabled(true);
05 saveAsAction->setEnabled(true);
06 imageLabel->setPixmap(QPixmap::fromImage(thread.image()));
07 setWindowModified(true);
08 statusBar()->showMessage(tr("Ready"), 2000);
09 }
Слот allTransactionsDone() вызывается, когда очередь транзакций TransactionThread становится пустой.
Теперь давайте рассмотрим класс TransactionThread:
01 class TransactionThread : public QThread
02 {
03 Q_OBJECT
04 public:
05 void addTransaction(Transaction *transact);
06 void setImage(const QImage &image);
07 QImage image();
08 signals:
09 void transactionStarted(const QString &message);
10 protected:
11 void run();
12 private:
13 QMutex mutex;
14 QImage currentImage;
15 QQueue transactions;
16 };
Класс TransactionThread содержит список обрабатываемых транзакций, которые выполняются по очереди в фоновом режиме.
01 void TransactionThread::addTransaction(Transaction *transact)
02 {
03 QMutexLocker locker(&mutex);
04 transactions.enqueue(transact);
05 if (!isRunning())
06 start();
07 }
Функция addTransaction() добавляет транзакцию в очередь транзакций и запускает поток транзакции, если он еще не выполняется. Доступ к переменной—члену transactions защищается мьютексом, потому что главный поток мог бы ее модифицировать функцией addTransaction() во время прохода по транзакциям transactions вторичного потока.
01 void TransactionThread::setImage(const QImage &image)
02 {
03 QMutexLocker locker(&mutex);
04 currentImage = image;
05 }
06 QImage TransactionThread::image()
07 {
08 QMutexLocker locker(&mutex);
09 return currentImage;
10 }
Функции setImage() и image() позволяют главному потоку установить изображение, для которого будут выполняться транзакции, и получить обработанное изображение после завершения всех транзакций. И вновь мы защищаем доступ к переменной—члену при помощи мьютекса.
01 void TransactionThread::run()
02 {
03 Transaction *transact;
04 forever {
05 mutex.lock();
06 if (transactions.isEmpty()) {
07 mutex.unlock();
08 break;
09 }
10 QImage oldImage = currentImage;
11 transact = transactions.dequeue();
12 mutex.unlock();
13 emit transactionStarted(transact->message());
14 QImage newImage = transact->apply(oldImage);
15 delete transact;
16 mutex.lock();
17 currentImage = newImage;
18 mutex.unlock();
19 }
20 }
Функция run() просматривает очередь транзакций и по очереди выполняет все транзакции путем вызова для них функции apply().
После старта транзакции мы генерируем сигнал transactionStarted() с сообщением, выводимым в строке состояния приложения. Когда обработка всех транзакций завершается, функция run() возвращает управление и QThread генерирует сигнал finished().
01 class Transaction
02 {
03 public:
04 virtual ~Transaction() { }
05 virtual QImage apply(const QImage &image) = 0;
06 virtual QString message() = 0;
07 };
Класс Transaction является абстрактным базовым классом, предназначенным для определения операций, которые пользователь может выполнять с изображением. Виртуальный деструктор необходим, потому что нам приходится удалять экземпляры подклассов Transaction через указатель transaction. (Кроме того, если мы его не предусмотрим, некоторые компиляторы выдадут предупреждение.) Transaction имеет три конкретных подкласса: FlipTransaction, ResizeTransaction и ConvertDepthTransaction. Нами будет рассмотрен только подкласс FlipTransaction; другие два подкласса имеют аналогичное определение.
01 class FlipTransaction : public Transaction
02 {
03 public:
04 FlipTransaction(Qt::Orientation orientation);
05 QImage apply(const QImage &image);
06 QString message();
07 private:
08 Qt::Orientation orientation;
09 };
Конструктор FlipTransaction принимает один параметр, который задает ориентацию зеркального отражения (по горизонтали или по вертикали).
01 QImage FlipTransaction::apply(const QImage &image)
02 {
03 return image.mirrored(
04 orientation == Qt::Horizontal, orientation == Qt::Vertical);
05 }
Функция apply() вызывает QImage::mirrored() для объекта QImage, полученного в виде параметра, и возвращает сформированный объект QImage.
01 QString FlipTransaction::message()
02 {
03 if (orientation == Qt::Horizontal) {
04 return QObject::tr("Flipping image horizontally...");
05 } else {
06 return QObject::tr("Flipping image vertically...");
07 }
08 }
Функция messageStr() возвращает сообщение, отображаемое в строке состояния в ходе выполнения операции. Данная функция вызывается из функции transactionThread::run(), кoгдa гeнepиpyeтcя cигнaл transactionStarted().
Применение классов Qt во вторичных потоках
Функция называется потокозащищенной (thread—safe), если она может спокойно вызываться одновременно из нескольких потоков. Если две такие функции вызываются из различных потоков и совместно используют одинаковые данные, результат всегда будет вполне определенным. Это определение можно расширить на класс, и тогда класс будет называться потокозащищенным, если все его функции могут вызываться одновременно из различных потоков, не мешая работе друг друга, если они даже работают с одним и тем же объектом.
В Qt потокозащищенными являются классы QMutex, QMutexLocker, QReadWriteLock, QReadLocker, QWriteLocker, QSemaphore, QThreadStorage, QWaitCondition и часть программного интерфейса QThread. Кроме того, несколько функций являются потокозащищенными, в частности QObject::connect(), QObject::disconnect(), QCoreApplication::postEvent(), QCoreApplication::removePostedEvent() и QCoreApplication::removePostedEvents().
Большинство классов Qt неграфического интерфейса удовлетворяют менее строгому ограничению: они являются реентерабельными (reentrant). Класс называется реентерабельным, если разные его экземпляры могут одновременно использоваться разными потоками. Однако одновременный доступ к одному реентерабельному объекту при многопоточной обработке недостаточно надежен и должен контролироваться при помощи мьютекса. Реентерабельность классов отмечается в справочной документации Qt. Обычно любой класс С++, который не использует глобальные переменные (или, другими словами, совместно используемые данные), является реентерабельным.
Читать дальшеИнтервал:
Закладка: