Функция run()
просматривает очередь транзакций и по очереди выполняет все транзакции путем вызова для них функции apply().После старта транзакции мы генерируем сигнал transactionStarted()
с сообщением, выводимым в строке состояния приложения. Когда обработка всех транзакций завершается, функция run() возвращает управление и QThread генерирует сигнал finished().01 class Transaction
02 {
03 public:
04 virtual ~Transaction() { }
05 virtual QImage apply(const QImage ℑ) = 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 ℑ);
06 QString message();
07 private:
08 Qt::Orientation orientation;
09 };
Конструктор FlipTransaction
принимает один параметр, который задает ориентацию зеркального отражения (по горизонтали или по вертикали).01 QImage FlipTransaction::apply(const QImage ℑ)
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().