Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Поиск слов в файле в Qt(Mutex) 
:(
    Опции темы
oxanapal
Дата 3.10.2016, 12:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Мне нужно написать консольную программу:
Которая для заданного каталога файлов на диске находит файлы, содержащие заданное слово с использованием многопоточности. Программа должна вывести в столбик имена найденных файлов в алфавитном порядке.
Я сделалa програму  но нужно ее  было  еще переделать и сделать с Mutexом, и я  не  знаю правильно  ли я  сделала с ним. Посмотрите и скажите  верно ли все
Хедер:
Код
#ifndef FIND_WORD_IN_FILE_THREAD_H
#define FIND_WORD_IN_FILE_THREAD_H
 
#include <QThread>
#include <QString>
#include <QtDebug>
#include <QMutex>
 
class FindWordInFileThread : public QThread
{
public:
    FindWordInFileThread(const std::vector<QString>& filePath, const QString& word, size_t startIndex, size_t numElements, std::vector<QString>& foundFiles, QMutex* mutex);
    virtual void run();
 
private:
    const std::vector<QString>& mFilePath;
    const QString mWord;
    size_t mStartIndex;
    size_t mNumElements;
    std::vector<QString>& mFoundFiles;
    QMutex* mMutex;
};
 
#endif // FIND_WORD_IN_FILE_THREAD_H

CPP:
Код
#include "FindWordInFileThread.h"
 
#include <QFile>
#include <QTextStream>
#include <QFileInfo>
#include <QMutexLocker>
 
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)
{}
 
void FindWordInFileThread::run()
{
    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();
            QMutexLocker locker(mMutex);
            if (line.contains(mWord, Qt::CaseInsensitive))
            {
                mFoundFiles.push_back(QFileInfo(mFilePath[index]).fileName());
                break;
            }
        }
        file.close();
    }
}

Main:
Код
void FindWordInFiles(const QString& word, const size_t numThreads)
{
    QMutex mutex;
 
    QTime time(QTime::currentTime());
    std::srand(time.msecsSinceStartOfDay());
 
    std::vector<QThread*> threads;
    threads.reserve(numThreads);
 
    QDirIterator dirIt("D:/11", QDirIterator::Subdirectories);
 
    std::vector<QString> paths;
    while (dirIt.hasNext())
    {
        dirIt.next();
        if (QFileInfo(dirIt.filePath()).isFile())
        {
            if (QFileInfo(dirIt.filePath()).suffix() == "txt")
                paths.push_back(dirIt.filePath());
        }
    }
 
    const std::vector<Range> ranges = GenerateRanges(numThreads, paths.size());
    std::vector<QString> foundFiles;
 
    time.start();
    for (size_t index = 0; index < numThreads; ++index)
        threads.push_back(new FindWordInFileThread(paths, word, ranges[index].mStart, ranges[index].mLength, foundFiles, &mutex));
 
    for (size_t index = 0; index < numThreads; ++index)
        threads[index]->start();
 
    for (size_t index = 0; index < numThreads; ++index)
        threads[index]->wait();
    const int elapsedMs = time.elapsed();
 
    std::sort(foundFiles.begin(), foundFiles.end());
 
    qDebug() << "Elapsed time(ms): " << elapsedMs;
    for (size_t index  = 0; index < foundFiles.size(); ++index)
        qDebug() << foundFiles[index];
 
    for (size_t index = 0; index < numThreads; ++index)
        delete threads[index];
}
 
int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    const int idealThreadCount = QThread::idealThreadCount();
 
    qDebug() << "One Thread:";
    FindWordInFiles("pavlik", 1);
    qDebug() << "";
 
    qDebug() << "Two Thread:";
    FindWordInFiles("pavlik", 2);
    qDebug() << "";
 
    qDebug() << "Optimal Thread: ";
    qDebug() <<"Ideal Thread Count:" << idealThreadCount;
    FindWordInFiles("pavlik", idealThreadCount);
    qDebug() << "";
 
    qDebug() << "Twenty Thread: ";
    FindWordInFiles("pavlik", 20);
 
    return app.exec();
}



Это сообщение отредактировал(а) oxanapal - 3.10.2016, 12:12
PM MAIL   Вверх
ss
Дата 4.10.2016, 14:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



во втором участке кода, функ. void FindWordInFileThread::run() , строку 29  QMutexLocker locker(mMutex); можно
поставить в строку 31
...
            if (line.contains(mWord, Qt::CaseInsensitive))
            {
             QMutexLocker locker(mMutex);
...

т.к. QMutexLocker  блокирует || выполнения while. Все потоки стопорятся на проверке.
пусть проверка выполняется в каждом потоке своя а результат будет записываться по очереди для потоков  тем самым запись результата не будет влиять на поиск слова в строке для остальных потоков.

Это сообщение отредактировал(а) ss - 4.10.2016, 14:36
PM MAIL   Вверх
oxanapal
Дата 17.10.2016, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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





Всем добрый день. Я немного доделала програму, сделала в виде виджета, додал прогрес бар и т.д. Но наткнулась на проблему:
1) Выдает ошибку, но делал как в книжке: Професиональное програмирование Макс Шлее(стр 551) но в моему случаи не пашет. Тема:Обмен сообщениями, потоки и слоты, сигналы.
Какую мне выдает ошибку:
FindWordInFileThread.obj:-1: error: LNK2019: unresolved external symbol "public: void __cdecl FindWordInFileThread::complited(int)" (?complited@FindWordInFileThread@@QEAAXH@Z) referenced in function "public: virtual void __cdecl FindWordInFileThread::run(void)" (?run@FindWordInFileThread@@UEAAXXZ)
та
debug\FindFilesWidget.exe:-1: error: LNK1120: 1 unresolved externals
я думаю оно кричит через этот код(но в книге работает), подскажите как решить проблему:
Код
for (size_t index = 0; index < mThreads.size(); ++index)
            connect(mThreads[index], SIGNAL(complited(int)), mProgressBar, SLOT(progressChanged(int)));
_________________________________________________
emit complited(QFileInfo(mFilePath[index]).size());

код где это используется:
Код
void FindFilesWidget::startClicked()
{
    if(mActionState == ActionState::STOPPED)
    {
        mActionState == ActionState::RUNNING;
        mStartButton->setText("&Cancel");
        const int idealThreadCount = QThread::idealThreadCount();
        mThreads.reserve(idealThreadCount);
 
        QDirIterator dirIt(mSearchDirectoryLine->text(), QDirIterator::Subdirectories);
        std::vector<QString> paths;
        while (dirIt.hasNext())
        {
            dirIt.next();
            if (QFileInfo(dirIt.filePath()).isFile())
            {
                if (QFileInfo(dirIt.filePath()).suffix() == "txt")
                    paths.push_back(dirIt.filePath());
            }
        }
        for (int  index = 0; index < paths.size(); ++index)
        {
            QFileInfo fileInfo(paths[index]);
            mFileSize += fileInfo.size();
        }
        const std::vector<Range> ranges = GenerateRanges(idealThreadCount, paths.size());
        std::vector<QString> foundFiles;
 
        for (size_t index = 0; index < idealThreadCount; ++index)
            mThreads.push_back(new FindWordInFileThread(paths, mSearchWordLine->text(), ranges[index].mStart, ranges[index].mLength, foundFiles));
 
        for (size_t index = 0; index < mThreads.size(); ++index)
            connect(mThreads[index], SIGNAL(complited(int)), mProgressBar, SLOT(progressChanged(int)));
 
        for (size_t index = 0; index < idealThreadCount; ++index)
            mThreads[index]->start();
        for (size_t index = 0; index < idealThreadCount; ++index)
            mThreads[index]->wait();
 
        std::sort(foundFiles.begin(), foundFiles.end());
 
        for (size_t index = 0; index < idealThreadCount; ++index)
            delete mThreads[index];
 
        mFoundFilesList->clear();
        for (size_t index = 0; index < foundFiles.size(); ++index)
            mFoundFilesList->addItem(foundFiles[index]);
    }
    else
    {
        mActionState = ActionState::STOPPED;
        mStartButton->setText("&Start");
        for (size_t index = 0; index < mThreads.size(); ++index)
            mThreads[index]->exit();
    }
 
}

Код
void FindWordInFileThread::run()
{
    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))
            {
                mFoundFiles.push_back(QFileInfo(mFilePath[index]).filePath());
                break;
            }
        }
        emit complited(QFileInfo(mFilePath[index]).size());
        file.close();
    }
}

CPP файли:
Код
#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)
    : mFilePath(filePath)
    , mWord(word)
    , mStartIndex(startIndex)
    , mNumElements(numElements)
    , mFoundFiles(foundFiles)
{}
 
void FindWordInFileThread::run()
{
    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))
            {
                mFoundFiles.push_back(QFileInfo(mFilePath[index]).filePath());
                break;
            }
        }
        emit complited(QFileInfo(mFilePath[index]).size());
        file.close();
    }
}

Код
#include "FindFilesWidget.h"
#include "FindWordInFileThread.h"
#include <QDebug>
 
struct Range
{
    Range(size_t start, size_t length);
 
    size_t mStart;
    size_t mLength;
};
 
Range::Range(size_t start, size_t length)
    : mStart(start)
    , mLength(length)
{}
 
std::vector<Range> GenerateRanges(size_t numRanges, size_t numFiles)
{
    std::vector<Range> ranges;
    ranges.reserve(numRanges);
 
    const size_t minLength = numFiles / numRanges;
    const size_t modulo = numFiles % numRanges;
 
    for (size_t index = 0; index < modulo; ++index)
        ranges.push_back(Range(0, minLength + 1));
 
    for (size_t index = modulo; index < numRanges; ++index)
        ranges.push_back(Range(0, minLength));
 
    for (size_t index = 1; index < numRanges; ++index)
        ranges[index].mStart = ranges[index - 1].mStart + ranges[index - 1].mLength;
 
    return ranges;
}
 
FindFilesWidget::FindFilesWidget(QWidget *parent)
    : QWidget(parent)
    , mActionState(ActionState::STOPPED)
    , mFileSize(0)
{
    setWindowTitle("Search Files");
 
    QVBoxLayout* vLayout = new QVBoxLayout(this);
    vLayout->setSpacing(6);
    vLayout->setContentsMargins(11, 11, 11, 11);
    vLayout->addWidget(createSelectDirectoryGroup());
    vLayout->addWidget(createSearchWordGroup());
    vLayout->addWidget(createProgressBarGroup());
    vLayout->addWidget(createFoundFilesGroup());
    setLayout(vLayout);
 
    resize(600, 600);
}
 
void FindFilesWidget::startClicked()
{
    if(mActionState == ActionState::STOPPED)
    {
        mActionState == ActionState::RUNNING;
        mStartButton->setText("&Cancel");
        const int idealThreadCount = QThread::idealThreadCount();
        mThreads.reserve(idealThreadCount);
 
        QDirIterator dirIt(mSearchDirectoryLine->text(), QDirIterator::Subdirectories);
        std::vector<QString> paths;
        while (dirIt.hasNext())
        {
            dirIt.next();
            if (QFileInfo(dirIt.filePath()).isFile())
            {
                if (QFileInfo(dirIt.filePath()).suffix() == "txt")
                    paths.push_back(dirIt.filePath());
            }
        }
        for (int  index = 0; index < paths.size(); ++index)
        {
            QFileInfo fileInfo(paths[index]);
            mFileSize += fileInfo.size();
        }
        const std::vector<Range> ranges = GenerateRanges(idealThreadCount, paths.size());
        std::vector<QString> foundFiles;
 
        for (size_t index = 0; index < idealThreadCount; ++index)
            mThreads.push_back(new FindWordInFileThread(paths, mSearchWordLine->text(), ranges[index].mStart, ranges[index].mLength, foundFiles));
 
        for (size_t index = 0; index < mThreads.size(); ++index)
            connect(mThreads[index], SIGNAL(complited(int)), mProgressBar, SLOT(progressChanged(int)));
 
        for (size_t index = 0; index < idealThreadCount; ++index)
            mThreads[index]->start();
        for (size_t index = 0; index < idealThreadCount; ++index)
            mThreads[index]->wait();
 
        std::sort(foundFiles.begin(), foundFiles.end());
 
        for (size_t index = 0; index < idealThreadCount; ++index)
            delete mThreads[index];
 
        mFoundFilesList->clear();
        for (size_t index = 0; index < foundFiles.size(); ++index)
            mFoundFilesList->addItem(foundFiles[index]);
    }
    else
    {
        mActionState = ActionState::STOPPED;
        mStartButton->setText("&Start");
        for (size_t index = 0; index < mThreads.size(); ++index)
            mThreads[index]->exit();
    }
 
}
 
void FindFilesWidget::progressChanged(int number)
{
    mProgressBar->setValue(mProgressBar->value() + ((number / mFileSize)* 100));
}
 
void FindFilesWidget::selectDirectoryClicked()
{
    QString selectedDirectory = QFileDialog::getExistingDirectory(this, tr("Open Directory"), mSearchDirectoryLine->text(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
    mSearchDirectoryLine->setText(selectedDirectory);
}
 
QGroupBox* FindFilesWidget::createSelectDirectoryGroup()
{
    QGroupBox* selectDirectoryGroup = new QGroupBox("&Select directory:");
    QPushButton* selectDirectoryButton = new QPushButton("Select", selectDirectoryGroup);
    mSearchDirectoryLine = new QLineEdit(tr("D:/"), selectDirectoryGroup);
 
    QHBoxLayout* hLayout = new QHBoxLayout();
    hLayout->setSpacing(6);
    hLayout->addWidget(mSearchDirectoryLine);
    hLayout->addWidget(selectDirectoryButton);
 
    connect(selectDirectoryButton, SIGNAL(clicked()), SLOT(selectDirectoryClicked()));
 
    selectDirectoryGroup->setLayout(hLayout);
    return selectDirectoryGroup;
}
 
QGroupBox* FindFilesWidget::createSearchWordGroup()
{
    QGroupBox* searchWordGroup = new QGroupBox("&Search word:");
    mSearchWordLine = new QLineEdit(searchWordGroup);
    mStartButton = new QPushButton("&Start");
 
    QHBoxLayout* hLayout = new QHBoxLayout();
    hLayout->setSpacing(6);
    hLayout->setContentsMargins(11, 11, 11, 11);
    hLayout->addWidget(mSearchWordLine);
    hLayout->addWidget(mStartButton);
 
    connect(mStartButton, SIGNAL(clicked()), SLOT(startClicked()));
 
    searchWordGroup->setLayout(hLayout);
    return searchWordGroup;
}
 
QGroupBox* FindFilesWidget::createProgressBarGroup()
{
    QGroupBox* progressBarGroup = new QGroupBox("&Progress Bar:");
    mProgressBar = new QProgressBar(progressBarGroup);
 
    QHBoxLayout* hLayout = new QHBoxLayout();
    hLayout->setSpacing(6);
    hLayout->setContentsMargins(11, 11, 11, 11);
    hLayout->addWidget(mProgressBar);
    mProgressBar->setMaximum(100);
    mProgressBar->setMinimumWidth(500);
    mProgressBar->setAlignment(Qt::AlignCenter);
 
    progressBarGroup->setLayout(hLayout);
    return progressBarGroup;
}
 
QGroupBox* FindFilesWidget::createFoundFilesGroup()
{
    QGroupBox* foundFilesGroup = new QGroupBox("&Found files:");
    mFoundFilesList = new QListWidget(foundFilesGroup);
 
    QHBoxLayout* hLayout = new QHBoxLayout();
    hLayout->setSpacing(6);
    hLayout->setContentsMargins(11, 11, 11, 11);
    hLayout->addWidget(mFoundFilesList);
 
    foundFilesGroup->setLayout(hLayout);
    return foundFilesGroup;
}



Присоединённый файл ( Кол-во скачиваний: 0 )
Присоединённый файл  вывывывы.png 5,02 Kb
PM MAIL   Вверх
ss
Дата 17.10.2016, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

FindWordInFileThread.obj:-1: error: LNK2019: unresolved external symbol "public: void __cdecl FindWordInFileThread::complited(int)" (?complited@FindWordInFileThread@@QEAAXH@Z) referenced in function "public: virtual void __cdecl FindWordInFileThread::run(void)" (?run@FindWordInFileThread@@UEAAXXZ)


линкер говорит что он не может найти реализацию метода complited(int) ,описанного в h-файле, в файле cpp.
Нужно проверить описание и реализацию методов. Обратить внимание на типы параметров у методов. Все методы описанные в h-файле должны иметь реализацию (тело)

Так же какое-то несоответствие с методом run(void). Возможно нет слова "override" в перегруженном методе.
PM MAIL   Вверх
oxanapal
Дата 17.10.2016, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(ss @ 17.10.2016,  15:05)
Цитата

FindWordInFileThread.obj:-1: error: LNK2019: unresolved external symbol "public: void __cdecl FindWordInFileThread::complited(int)" (?complited@FindWordInFileThread@@QEAAXH@Z) referenced in function "public: virtual void __cdecl FindWordInFileThread::run(void)" (?run@FindWordInFileThread@@UEAAXXZ)


линкер говорит что он не может найти реализацию метода complited(int) ,описанного в h-файле, в файле cpp.
Нужно проверить описание и реализацию методов. Обратить внимание на типы параметров у методов. Все методы описанные в h-файле должны иметь реализацию (тело)

Так же какое-то несоответствие с методом run(void). Возможно нет слова "override" в перегруженном методе.

зараз кричит  на прогрес  бар:
QObject::connect: No such slot QProgressBar::progressChanged(int) in ..\FindFilesWidget\FindFilesWidget.cpp:89
но такой слот есть
Код

void FindFilesWidget::progressChanged(int number)
{
    mProgressBar->setValue(mProgressBar->value() + ((number / mFileSize)* 100));
}


Это сообщение отредактировал(а) oxanapal - 17.10.2016, 16:04
PM MAIL   Вверх
oxanapal
Дата 17.10.2016, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Нашлась  ошибка:
Обжекст не  додала в начало:
Код

#ifndef FIND_WORD_IN_FILE_THREAD_H
#define FIND_WORD_IN_FILE_THREAD_H

#include <QThread>
#include <QString>
#include <QtDebug>

class FindWordInFileThread : public QThread
{
    Q_OBJECT
public:
    FindWordInFileThread(const std::vector<QString>& filePath, const QString& word, size_t startIndex, size_t numElements, std::vector<QString>& foundFiles);
    virtual void run();
signals:
    void completed(qint64);
private:
    const std::vector<QString>& mFilePath;
    const QString mWord;
    size_t mStartIndex;
    size_t mNumElements;
    std::vector<QString>& mFoundFiles;
};

#endif // FIND_WORD_IN_FILE_THREAD_H


Но  прогрес  бар так и не  работает(

PM MAIL   Вверх
ss
Дата 17.10.2016, 20:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

QObject::connect: No such slot QProgressBar::progressChanged(int) in ..\FindFilesWidget\FindFilesWidget.cpp:89
но такой слот есть


Вы думаете, компилятор вас обманывает ?

здесь ..\FindFilesWidget\FindFilesWidget.cpp:89 указан виджет QProgressBar а слот progressChanged(int number) был описан в классе FindFilesWidget.
Не тот задан класс (mProgressBar)


Это сообщение отредактировал(а) ss - 17.10.2016, 20:27
PM MAIL   Вверх
oxanapal
Дата 18.10.2016, 10:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



ss,  я   там  лаханулась,  нужно  было this  вместо progressBar в connect 
Код

connect(mThreads[index], SIGNAL(complited(int)), mProgressBar, SLOT(progressChanged(int)));

нужно
Код

connect(mThreads[index], SIGNAL(complited(int)),this, SLOT(progressChanged(int)));

но  теперь  другая  проблема, через wait у меня кнопка кансел срабатывает и прогрес  бар показывает результат  после  окончания  работы.  И как  с  этим  боротся  хз
PM MAIL   Вверх
ss
Дата 18.10.2016, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



не совсем понятно " wait у меня кнопка кансел срабатывает и прогрес  бар показывает результат  после  окончания  работы.  И как  с  этим  боротся  хз "

прогрессбар изменяет свою шкалу когда нажали кнопу. Нужно  чтобы прогрессбар отображал прогресс на каждом этапе выполнения т.е. постепенно заполнялся ?
PM MAIL   Вверх
oxanapal
Дата 18.10.2016, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



ss,  именно, а у меня через wait прорес сразу показывает  100% когда  все слова нашла програма тоесть при окончании програмы. а нужно чтобы постпенно заполнялся
я скидаю весь проект, так как много уже изменений сделал и сложно суда частями скидать чтобы понятно  было 

Это сообщение отредактировал(а) oxanapal - 18.10.2016, 13:10

Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  FindFilesWidget.zip 6,82 Kb
PM MAIL   Вверх
ss
Дата 19.10.2016, 15:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



на счет постепенного заполнения то :
скорее всего потоки слишком быстро выполняют свою работу. 
Можно попробовать поставить задержку в цикле обработки файлов (где emit complited).
QThread::currentThread()->msleep(1000); // 1000 - 1 сек
и поставить вывод в консоль сообщения чтобы убедиться в постоянном вызове слота.

void FindFilesWidget::progressChanged(int number)
{
qDebug()<< number;
    mProgressBar->setValue(mProgressBar->value() + ((number / mFileSize)* 100));
}
PM MAIL   Вверх
oxanapal
Дата 19.10.2016, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



ss,  cделала,  не помогло
PM MAIL   Вверх
ss
Дата 19.10.2016, 22:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



из кода в архиве:

сигнал progressChanged 
используется в void FindWordInFileThread::run() а объявлен в FindFilesWidget
тогда надо emit FindFilesWidget.progressChanged  ; где FindFilesWidget будет экземпляр класса

//--------------------------------------------
void FindWordInFileThread::run()

строка if (mIsCancelled) 
нужно файл закрыть

//--------------------------------------------
класс
FindWordInFileThread
сигнал void completed(QString, bool); 

а связывание connect(mThreads[index], SIGNAL(completed(qint64)), this, SLOT(progressChanged(qint64)));

типы не соответствуют. Не тот тип , нет и сигнала. Это должно в консоль выводиться.

да и все равно сигнал будет использовать отложенные соединения (queued connections).
PM MAIL   Вверх
ss
Дата 21.10.2016, 03:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



на чистом проекте делал изменение прогрессбара в потоках. 
Использовал общую переменную для сохранения значения прогрессбара _valueIndicator и таймер на форме который периодически проверяет значение переменной и делает обновление прогрессбара

Код

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QThread>
#include <QMutex>
#include <QVector>

namespace Ui {
class MainWindow;
}


class Finder: public QThread
{
    Q_OBJECT

public:
    Finder(size_t* valueIndicator);
protected:
    virtual void run() override;
private:

    size_t* _valueIndicator;
    QMutex  _mutex;
};


class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

protected:
    void timerEvent(QTimerEvent *event);
private slots:
    void on_btnStart_clicked();

private:
    Ui::MainWindow *ui;

    size_t _valueIndicator;
    int _timerId;

    QVector<Finder*> _pool;
    QMutex _mutex;
};

#endif // MAINWINDOW_H



Код

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QMutexLocker>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    _valueIndicator(0)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    killTimer(_timerId);   
    foreach(auto &o, _pool)
    {
        o->quit();
        o->wait();
        delete o;
    }

    delete ui;
}

void MainWindow::timerEvent(QTimerEvent *event)
{
    ui->progressBar->setValue(_valueIndicator);
    qDebug()<<_valueIndicator;
}

void MainWindow::on_btnStart_clicked()
{
    _pool.reserve(4);
    for(int i = 0; i < 4; ++i)
    {
        Finder* o = new Finder(&_valueIndicator);
        _pool.push_back(o);
        o->start();
        QThread::currentThread()->msleep(100);  //задержка для потоков, чтобы индикатор двигался плавнее
    }

    _timerId = startTimer(100);

}

Finder::Finder(size_t *valueIndicator):
    _valueIndicator( valueIndicator )
{

}

void Finder::run()
{
   forever
    {
        QThread::currentThread()->msleep(1000);
        QMutexLocker l(&_mutex);

        (*_valueIndicator) ++;
        if(*_valueIndicator > 100)
        {
            (*_valueIndicator) = 0;
        }
    }
}




Присоединённый файл ( Кол-во скачиваний: 1 )
Присоединённый файл  twoCpp.zip 2,33 Kb
PM MAIL   Вверх
oxanapal
Дата 21.10.2016, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



ss,  посмотрел. я  так само  делаю. кроме 
Код

->quit();

и походу  нужно  еще timerEvent сделать, у меня нету.



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

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

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


 




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


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

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