Форум программистов
 
Расширенный поиск
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

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

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

Excel VBA, CAD, Софт, ОС, Windows, Ubuntu, Android, VPS
Win Api, Assembler, C++, Java, Pascal, Lazarus, Delphi, OpenGL, DirectX
C#, Qt, .NET, ASP.NET, Windows Forms, ADO.NET, Framework, WPF, UWP, WinRT, XAML
HTML, CSS, JavaScript, Ajax, PHP, Perl, Python, Ruby, SQL, WordPress, API, XML, JSON, ActionScript, Flash

Ответ
 
Опции темы
Старый 17.10.2016, 11:55   #1
stasJun
Форумчанин
 
Регистрация: 17.10.2016
Сообщений: 95
Репутация: 10
По умолчанию Поиск слов в файле в Qt

Мне нужно написать программу:
Которая для заданного каталога файлов на диске находит файлы, содержащие заданное слово с использованием многопоточности. Программа должна вывести в столбик имена найденных файлов в алфавитном порядке.

Я сделал в виде виджета, додал прогрес бар и т.д. Но наткнулся на проблему:
1) Выдает ошибку, но делал как в книжке: Професиональное програмирование Макс Шлее(стр 551) но в моему случаи не пашет. Тема:Обмен сообщениями, потоки и слоты, сигналы.
Какую мне выдает ошибку:
FindWordInFileThread.obj:-1: error: LNK2019: unresolved external symbol "public: void __cdecl FindWordInFileThread::complited(int )" (?complited@FindWordInFileThread@@Q EAAXH@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();
    }
}


Последний раз редактировалось stasJun; 17.10.2016 в 11:59.
stasJun вне форума   Ответить с цитированием
Старый 17.10.2016, 11:55   #2
stasJun
Форумчанин
 
Регистрация: 17.10.2016
Сообщений: 95
Репутация: 10
По умолчанию

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;
}

stasJun вне форума   Ответить с цитированием
Старый 17.10.2016, 11:56   #3
stasJun
Форумчанин
 
Регистрация: 17.10.2016
Сообщений: 95
Репутация: 10
По умолчанию

Скрин програмы
Изображения
Тип файла: png вывывывы.png (5.0 Кб, 19 просмотров)
stasJun вне форума   Ответить с цитированием
Старый 17.10.2016, 12:09   #4
Alex11223
Модератор
Заслуженный модератор
 
Регистрация: 12.01.2011
Сообщений: 12,358
Репутация: 2542

icq: 512-7шесть5
skype: alexp.frl
По умолчанию

Что в FindWordInFileThread.h?
Может быть вы сигнал complited объявили не в секции signals.

Кстати, правильно это слово пишется как completed.

И в Qt5 есть более удобный и безопасный (выдаст ошибку компиляции если указано неправильное имя и т.п.) способ подписки на сигналы.
https://wiki.qt.io/New_Signal_Slot_Syntax
Alex11223 на форуме   Ответить с цитированием
Старый 17.10.2016, 16:02   #5
stasJun
Форумчанин
 
Регистрация: 17.10.2016
Сообщений: 95
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
Что в FindWordInFileThread.h?
Может быть вы сигнал complited объявили не в секции signals.

Кстати, правильно это слово пишется как completed.

И в Qt5 есть более удобный и безопасный (выдаст ошибку компиляции если указано неправильное имя и т.п.) способ подписки на сигналы.
https://wiki.qt.io/New_Signal_Slot_Syntax
Нет , обявил там где нужно
Код:

#ifndef FINDFILESWIDGET_H
#define FINDFILESWIDGET_H

#include <QtWidgets>

class FindFilesWidget : public QWidget
{
    Q_OBJECT

public:
    enum ActionState
    {
        RUNNING,
        STOPPED,
    };
    FindFilesWidget(QWidget* parent = 0);

public slots:
    void startClicked();
    void selectDirectoryClicked();
    void progressChanged(int);

private:
    QGroupBox* createSelectDirectoryGroup();
    QGroupBox* createSearchWordGroup();
    QGroupBox* createProgressBarGroup();
    QGroupBox* createFoundFilesGroup();

    QLineEdit* mSearchDirectoryLine;
    QListWidget* mFoundFilesList;
    QLineEdit* mSearchWordLine;
    QPushButton* mStartButton;
    QProgressBar* mProgressBar;
    ActionState mActionState;
    std::vector<QThread*> mThreads;
    size_t mFileSize;
};

#endif // FINDFILESWIDGET_H

Код:

#ifndef FIND_WORD_IN_FILE_THREAD_H
#define FIND_WORD_IN_FILE_THREAD_H

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

class FindWordInFileThread : public QThread
{
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 complited(int);
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

stasJun вне форума   Ответить с цитированием
Старый 17.10.2016, 16:05   #6
stasJun
Форумчанин
 
Регистрация: 17.10.2016
Сообщений: 95
Репутация: 10
По умолчанию

Архив проекта
Вложения
Тип файла: zip FindFilesWidget.zip (6.5 Кб, 1 просмотров)
stasJun вне форума   Ответить с цитированием
Старый 17.10.2016, 16:41   #7
Alex11223
Модератор
Заслуженный модератор
 
Регистрация: 12.01.2011
Сообщений: 12,358
Репутация: 2542

icq: 512-7шесть5
skype: alexp.frl
По умолчанию

Q_OBJECT надо добавить.

Еще QFileInfo size возвращает int64 (qint64), а не int.
Alex11223 на форуме   Ответить с цитированием
Старый 17.10.2016, 16:46   #8
stasJun
Форумчанин
 
Регистрация: 17.10.2016
Сообщений: 95
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
Q_OBJECT надо добавить.

Еще QFileInfo size возвращает int64 (qint64), а не int.
int64 (qint64) и как это исправить?

Последний раз редактировалось stasJun; 17.10.2016 в 16:53.
stasJun вне форума   Ответить с цитированием
Старый 17.10.2016, 16:52   #9
Alex11223
Модератор
Заслуженный модератор
 
Регистрация: 12.01.2011
Сообщений: 12,358
Репутация: 2542

icq: 512-7шесть5
skype: alexp.frl
По умолчанию

Цитата:
Сообщение от stasJun Посмотреть сообщение
куда именно добавить?
куда и всегда, в начало класса.


Цитата:
Сообщение от stasJun Посмотреть сообщение
int64 (qint64) и как это исправить?
в completed заменить тип данных на qint64
Alex11223 на форуме   Ответить с цитированием
Старый 17.10.2016, 16:54   #10
stasJun
Форумчанин
 
Регистрация: 17.10.2016
Сообщений: 95
Репутация: 10
По умолчанию

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



в completed заменить тип данных на qint64
уже програма работает, но прогрем бар не работает((
и этот код походу тоже не работает(который названия кнопки изменяет (отмета и старт)):
Кричит: QObject::connect: No such slot QProgressBar:rogressChanged(int) in
Код:

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(completed(qint64)), 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();
    }

}


Последний раз редактировалось stasJun; 17.10.2016 в 17:00.
stasJun вне форума   Ответить с цитированием
Ответ



Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

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




18:09.


Powered by vBulletin® Version 3.8.8 Beta 2
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.

Покупайте на сайте www.skinon.ru уникальные чехлы и наклейки для телефонов.
купить трафик


как улучшить посещаемость, а также решения по монетизации сайтов, видео и приложений

RusProfile.ru


Справочник российских юридических лиц и организаций.
Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru