crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

> ProgressBar на QtConcurrent
Fitz
  опции профиля:
сообщение 22.11.2010, 15:30
Сообщение #1


Студент
*

Группа: Новичок
Сообщений: 13
Регистрация: 22.11.2010
Пользователь №: 2207

Спасибо сказали: 0 раз(а)




Репутация:   0  


Уважаемые, хочу прикрутить к терминалу COM-порта ProgressBar загрузки файла в порт.
Сделав, соответстветственно, загрузку файла отдельным потоком.
Заюзал Qt'шный экзампл Progress Dialog, где используют QtConcurrent.

Код:
mainwindow.h
class MainWindow : public QMainWindow, public Ui::UARTxxx{
    Q_OBJECT
private:
    void loadFile(const QString &fileName);
public slots:
    void open();
}

mainwindow.cpp
void MainWindow::loadFile(const QString &fileName)
{
     QFile file(fileName);
     if (!file.open(QIODevice::ReadOnly))
       {
         QMessageBox::warning(this, tr("Application"),
                              tr("Cannot read file %1:\n%2.")
                              .arg(fileName)
                              .arg(file.errorString()));
         return;
       }

                // посылка QByteArray прочитанный из файла в порт

}

void MainWindow::open()
{
        QString fileName = QFileDialog::getOpenFileName(this);
        if (!fileName.isEmpty())
        {
            QProgressDialog dialog;
            QList<QString> fileList;
            fileList.append(fileName);
            dialog.setLabelText(QString("Downloading..."));

            QFutureWatcher<void> futureWatcher;
            connect(&futureWatcher, SIGNAL(finished()), &dialog, SLOT(reset()));
            connect(&dialog, SIGNAL(canceled()), &futureWatcher, SLOT(cancel()));
            connect(&futureWatcher, SIGNAL(progressRangeChanged(int, int)), &dialog, SLOT(setRange(int, int)));
            connect(&futureWatcher, SIGNAL(progressValueChanged(int)), &dialog, SLOT(setValue(int)));

            futureWatcher.setFuture(QtConcurrent::map(fileList, MainWindow::loadFile));

            dialog.exec();

            futureWatcher.waitForFinished();
     }
}


Компилятор ругается в futureWatcher.setFuture(QtConcurrent::map(fileList, MainWindow::loadFile));, мол там нужен адрес функции, однако и подстановка адреса не помогает.
Что делаю не так?
Возможно есть более грамотное решение с QThread, подскажите.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
 
Начать новую тему
Ответов
Fitz
  опции профиля:
сообщение 24.11.2010, 20:14
Сообщение #2


Студент
*

Группа: Новичок
Сообщений: 13
Регистрация: 22.11.2010
Пользователь №: 2207

Спасибо сказали: 0 раз(а)




Репутация:   0  


После осознания наваял следующую конструкцию, котороая, как ни странно, заработала.

Создал отдельный класс прошивки:
ufirmware.h
class uFirmware
{
public:
    uFirmware(AbstractSerial *inPort, QString fileName);
    ~uFirmware();
    bool loadFile();

private:
    AbstractSerial *uPort;
    QString uFileName;
};

ufirmware.cpp
uFirmware::uFirmware(AbstractSerial *inPort, QString fileName)
{
    uPort = inPort;
    uFileName = fileName;
}

bool uFirmware::loadFile()
{
        QFile fFile(uFileName);
        QByteArray fileToArray = fFile.readAll();
      // бла-бла-бла

      uPort->write(fileToArray);
}

Теперь применение:
mainwindow.cpp
void MainWindow::open()
{
        QString fileName = QFileDialog::getOpenFileName(this);
        if (!fileName.isEmpty())
        {
QProgressDialog dialog;
            QList<uFirmware> fList;
            fList.append(uFirmware(port, fileName));
            dialog.setLabelText(QString("Downloading..."));

            QFutureWatcher<void> futureWatcher;
            connect(&futureWatcher, SIGNAL(finished()), &dialog, SLOT(reset()));
            connect(&dialog, SIGNAL(canceled()), &futureWatcher, SLOT(cancel()));
            connect(&futureWatcher, SIGNAL(progressRangeChanged(int, int)), &dialog, SLOT(setRange(int, int)));
            connect(&futureWatcher, SIGNAL(progressValueChanged(int)), &dialog, SLOT(setValue(int)));

            futureWatcher.setFuture(QtConcurrent::map(fList, &uFirmware::loadFile));

            dialog.exec();

            futureWatcher.waitForFinished();
     }
}


Вопрос раз: необходимо ли делать класс uFirmware потокобезопасным?
Вопрос два: код работает не совсем так, как мечталось - futureWatcher вычисляет только работу метода класса, а вот используемый им метод сторонней библиотеки AbstractSerial::write(QByteArray a)(в интересах которого, собственно, и выделяется отдельный поток) в расчет не берется.
Выходит надо работать напрямую с классом AbstractSerial? Но тогда каким образом передавать методу записи в порт write(QByteArray a) этот внешний параметр?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Сообщений в этой теме


Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 14.1.2025, 12:16