Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Qt и кроссплатформенное программирование С/С++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.10.2016, 22:43   #31
stasJun
Пользователь
 
Регистрация: 17.10.2016
Сообщений: 95
По умолчанию

Я переделал через Мютекс, думал может так будет быстрее работать и правильно нифига(wait и т.д)(
Код:
#include "FindWordInFileThread.h"

#include <QFile>
#include <QTextStream>
#include <QFileInfo>

FindWordInFileThread::FindWordInFileThread(const std::vector<QString>& filePath, const QString& word, size_t startIndex, size_t numElements, std::vector<QString>& foundFiles, QMutex* mutex)
    : mFilePath(filePath)
    , mWord(word)
    , mStartIndex(startIndex)
    , mNumElements(numElements)
    , mFoundFiles(foundFiles)
    , mMutex(mutex)
    , mIsCancelled(false)
{}

void FindWordInFileThread::run()
{
    mCachedFiles.clear();
    for (size_t index = mStartIndex; index < mStartIndex + mNumElements; ++index)
    {
        QFile file(mFilePath[index]);
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
            return;

        QTextStream textStream(&file);
        while (!textStream.atEnd())
        {
            QString line = textStream.readLine();
            if (line.contains(mWord, Qt::CaseInsensitive))
            {
                mCachedFiles.push_back(QFileInfo(mFilePath[index]).fileName());
                break;
            }
            if (mIsCancelled)
                return;
        }
        emit completed(QFileInfo(mFilePath[index]).size());
        file.close();
    }
    if (!mCachedFiles.empty())
    {
        QMutexLocker locker(mMutex);
        mFoundFiles.insert(mFoundFiles.end(), mCachedFiles.begin(), mCachedFiles.end());
    }
}
void FindWordInFileThread::cancelClicked()
{
    mIsCancelled = true;
}

Последний раз редактировалось stasJun; 17.10.2016 в 23:09.
stasJun вне форума Ответить с цитированием
Старый 17.10.2016, 23:08   #32
stasJun
Пользователь
 
Регистрация: 17.10.2016
Сообщений: 95
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
а, насчет отмены и завершения, я не заметил, что там есть wait после запуска потоков.

Тогда отмена вообще не может работать, у вас же UI поток занят ожиданием завершения потоков.

И прогресс по идее тоже не обновляется во время работы, только после завершения все сразу.
да, все сразу показывает. в конце. И как с этим бороться?
stasJun вне форума Ответить с цитированием
Старый 17.10.2016, 23:09   #33
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Причем тут мьютекс? я ж написал в чем проблема.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 17.10.2016, 23:54   #34
stasJun
Пользователь
 
Регистрация: 17.10.2016
Сообщений: 95
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
Причем тут мьютекс? я ж написал в чем проблема.
я не увидел ваш пост про wait сначала)
а как можно реализовать чтобы обойти wait? чтобы нормально прогрес бар работал и кансел
stasJun вне форума Ответить с цитированием
Старый 18.10.2016, 09:28   #35
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Не делать ничего после запуска потоков, всю обработку результата и т.п. делать только по сигналу (completed, ...)

Я бы сделал у потока 2 сигнала: completed и progressChanged.

Во втором просто передавать количество обработанных байтов: в цикле чтения если надо (только наверно лучше не каждую итерацию а как-то более редко) и в конце размер файла как сейчас.

А в completed наверно надо передавать имя файла и результат (в данном случае bool найдено/не найдено).
При его получении выводить результат и считать количество завершенных потоков для определения завершения всего поиска.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 18.10.2016, 10:54   #36
stasJun
Пользователь
 
Регистрация: 17.10.2016
Сообщений: 95
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
Не делать ничего после запуска потоков, всю обработку результата и т.п. делать только по сигналу (completed, ...)

Я бы сделал у потока 2 сигнала: completed и progressChanged.

Во втором просто передавать количество обработанных байтов: в цикле чтения если надо (только наверно лучше не каждую итерацию а как-то более редко) и в конце размер файла как сейчас.

А в completed наверно надо передавать имя файла и результат (в данном случае bool найдено/не найдено).
При его получении выводить результат и считать количество завершенных потоков для определения завершения всего поиска.
спасибо
я все прочитал что ві написали, и не совсем понял.
void completed(bool mIsCancelled);
а от как с progressChanged сделать я не понял(

Последний раз редактировалось stasJun; 18.10.2016 в 11:05.
stasJun вне форума Ответить с цитированием
Старый 18.10.2016, 11:40   #37
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Причем тут mIsCancelled?
Ну mIsCancelled конечно тоже можно сообщать в completed и часто это бывает удобно, но не обязательно и к основной задаче не относится.

Код:
run()
{
    bool found = false;

    while (чтение файла)
    {
          emit progressChanged(текущая_позиция_в_файле); // не обязательно

          if (нашли то что искали)
          {
               found = true;
               break;
          }
    }

    emit progressChanged(размер файла);
    emit completed(имя файла, found);
}
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

Последний раз редактировалось Alex11223; 18.10.2016 в 11:43.
Alex11223 вне форума Ответить с цитированием
Старый 18.10.2016, 12:12   #38
stasJun
Пользователь
 
Регистрация: 17.10.2016
Сообщений: 95
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
Причем тут mIsCancelled?
Ну mIsCancelled конечно тоже можно сообщать в completed и часто это бывает удобно, но не обязательно и к основной задаче не относится.

Код:
run()
{
    bool found = false;

    while (чтение файла)
    {
          emit progressChanged(текущая_позиция_в_файле); // не обязательно

          if (нашли то что искали)
          {
               found = true;
               break;
          }
    }

    emit progressChanged(размер файла);
    emit completed(имя файла, found);
}
переделал:
[CODE]signals:
void completed(QString, bool);
Код:
void FindWordInFileThread::run()
{
    bool found = false;
    mCachedFiles.clear();
    for (size_t index = mStartIndex; index < mStartIndex + mNumElements; ++index)
    {
        QFile file(mFilePath[index]);
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
            return;

        QTextStream textStream(&file);
        while (!textStream.atEnd())
        {
            QString line = textStream.readLine();
            if (line.contains(mWord, Qt::CaseInsensitive))
            {
                found = true;
                mCachedFiles.push_back(QFileInfo(mFilePath[index]).fileName());
                break;
            }
            if (mIsCancelled)
                return;
        }
        emit progressChanged(QFileInfo(mFilePath[index]).size());
        emit completed(QFileInfo(mFilePath[index]).fileName(), found);
        file.close();
    }
    if (!mCachedFiles.empty())
    {
        QMutexLocker locker(mMutex);
        mFoundFiles.insert(mFoundFiles.end(), mCachedFiles.begin(), mCachedFiles.end());
    }
}
но выдает ошибку так как void progressChanged(qint64);
у меня в виджете а не в класе поток.

и оно не знает такую функцию :
D:\Development\Pavlik\Qt\FindFilesW idget\FindWordInFileThread.cpp:40: error: C3861: 'progressChanged': identifier not found
и у меня функцияпринимает аргумент number
Код:
void FindFilesWidget::progressChanged(qint64  number)
{
    mBytesProcessed += number;
    mProgressBar->setValue(mBytesProcessed / (double) mFileSize * 100);
}
stasJun вне форума Ответить с цитированием
Старый 18.10.2016, 13:21   #39
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Ну видимо у вас нет сигнала с именем progressChanged в классе потока.

и пример выше был про случай когда один поток ищет только в одном файле, для переделывания под несколько файлов как тут надо не просто скопипастить
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

Последний раз редактировалось Alex11223; 18.10.2016 в 13:23.
Alex11223 вне форума Ответить с цитированием
Старый 18.10.2016, 13:50   #40
stasJun
Пользователь
 
Регистрация: 17.10.2016
Сообщений: 95
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
Ну видимо у вас нет сигнала с именем progressChanged в классе потока.

и пример выше был про случай когда один поток ищет только в одном файле, для переделывания под несколько файлов как тут надо не просто скопипастить
нету, он у меня этот поток в класе FindFilesWidget
stasJun вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Поиск слов в файле Stepan_P Linux (Ubuntu, Debian, Red Hat, CentOS, Mint) 0 25.12.2015 14:14
Поиск слов в текстовом файле slipkos Помощь студентам 4 02.06.2013 19:18
Поиск симметричных слов в файле Almost Паскаль, Turbo Pascal, PascalABC.NET 1 10.01.2013 08:53
Поиск слов в файле сушка Общие вопросы по программированию, компьютерный форум 1 08.04.2012 12:44
Поиск слов в текстовом файле svt Помощь студентам 8 07.11.2009 19:56