Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [QT4] межпоточное сигнал-слот соединение, QImage из вторичного потока в главный 
V
    Опции темы
DSan
Дата 29.4.2008, 23:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 10.2.2007

Репутация: нет
Всего: нет



Имеем:

программа по нажатию на директорию в дереве каталогов файловой системы отображает эскизы изображений из выбранной директории. Алгоритм формирования прост - загружается изображение в QImage, масштабируется до нужного размера и отображается в ListView в виде иконки. Создание эскиза вынесено во вторичный поток. После формирования эскиз передается в главный поток через сигнал-слот соединение для отображения.

Класс для формирования эскизов:

Код

class ThumbThread : public QThread {
    
    Q_OBJECT
    
public:
    ThumbThread() : stopped(false) {}
    void setThumbPath(const QString &path);
    void stop();
    void run();

signals:
    void showThumb(const QImage &, const QString &);

private:
    QString thumbPath;
    volatile bool stopped;
};

void ThumbThread::setThumbPath(const QString &path) {
    thumbPath = path;
}

void ThumbThread::stop() {
    stopped = true;
}

void ThumbThread::run() {
    
    ...
    
    for(int i = 0; i < fileList.count(); i++) {

        if(stopped)
            break;    

        ... // формируется эскиз resultImg
        
        emit showThumb(resultImg, fileName);        
    }
    
    stopped = false;
}


Главное окно (класс MainWindow):

Код

// конструктор
MainWindow::MainWindow() {
    
    ...
    // соединение
    connect(&thread, SIGNAL(showThumb(const QImage &, const QString &)), this, SLOT(thumbCreated(const QImage &, const QString &)));
}

// добавление эскиза в модель (отображается в соответствующем QListView)
void MainWindow::thumbCreated(const QImage &img, const QString &fileName) {
    QStandardItem *item = new QStandardItem();
    
    item->setData(QIcon(QPixmap::fromImage(img)), Qt::DecorationRole);
    item->setData(fileName, Qt::ToolTipRole);
    
    thumbModel->appendRow(item);
}

// слот для запуска потока при выборе директории в дереве каталогов
// thread объявлен как private член в классе MainWindow
void MainWindow::pathEntered() {
    
    // поток работает?
    if(thread.isRunning()) {
        thread.stop(); // останавливаем
        thread.wait(); // ждем, когда закончится обработка текущего на данный момент эскиза
    }
    
    thumbModel->clear(); // очищение модели с эскизами
    
    thread.setThumbPath(pathEdit->text()); // указание каталога для формирования эскизов
        
    thread.start();
}


Суть проблемы:

если не дожидаться, пока поток подгрузит _все_ эскизы выбранной директории, и выбрать другую, то после очистки модели первым будет отображен эскиз, который был сформирован последним перед остановкой потока. Т.е. получается, что эскиз, который формировался непосредственно перед остановкой потока, не успевает отобразиться в ListView и попадает уже в "новую партию" эскизов. Каким образом можно решить данную проблему?
PM   Вверх
JackYF
Дата 29.4.2008, 23:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 7
Всего: 162



Цитата(DSan @  29.4.2008,  22:01 Найти цитируемый пост)
Каким образом можно решить данную проблему? 

Вижу два возможных выхода:

1) прервать предыдущий рабочий поток, если он был, во время перехода на новый элемент в дереве
2) передать вместе с картинкой и некий ID запроса. Если это не последний запрос, не отображать эскиз.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
DSan
Дата 30.4.2008, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 10.2.2007

Репутация: нет
Всего: нет



Цитата(JackYF @ 29.4.2008,  23:48)
Вижу два возможных выхода:

1) прервать предыдущий рабочий поток, если он был, во время перехода на новый элемент в дереве
2) передать вместе с картинкой и некий ID запроса. Если это не последний запрос, не отображать эскиз.

Воспользовался вторым советом.

Спасибо, проблема решена.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0439 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.