Qt C++ - пример программы - несколько форм - как передать указатель на родительскую форму -обмен данными между формами- пример



#include "mainwindow.h"
#include < QApplication >
#include < QtCore\QtCore >
#include < QtGui\QtGui >
#include < QTextCodec > // для работы с кодировками



class UrlInfo
{
  public:
    QString url; // сам адрес
    QVector  < QString > files; // список файлов в которые он входит
    QVector  < int > line;// строка вхождения
    QVector  < int > col; // столбец вхождения

};

class ResultArray
{
  public:
    QVector  < UrlInfo* > urls; // массив с инфой о URL-ах

};

/*ниже дочерний и родительский класс взаимно используют друг друга в собственных
описаниях. Чтобы интерпретатор понял что к чему  - мы сначала их объявляем
- а потом только описываем - причём методы
родительского класса описываем вообще снаружи - а первое объявлеение дочерего класса
- чисто формальное, оно позволяет интерпретатору понять,
что мы вообще имеем дело с классом (хотя бы это) а не со случайно
нажатой комбинацией клавиш =))
*/

class NewWindow;

/* опишем класс
главного окна который наследует
функционал и свойства QMainWindow*/

class  myMainWindow:public QMainWindow
 {   Q_OBJECT // макрос необходимый для вссякого класса
     // который использует синтаксис Qt отличный от стандарта Си++
     // -в нашем случае - это описание слотов Qt

    public:
      myMainWindow (QWidget *parent = 0); // описываем конструктор
     //родитель по-умолчанию отсутствует

       // тоже самое,что слот, только метод (для вызова из другого класса)
       void opnNewWindow(QString path); // описываем реализацию снаружи

    public slots:
       void openNewWindow(); // реализацию слота опишем снаружи


    public:
        // хранит ссылку на второе(дополнительное)окно
    // NewWindow *someNewWindow;
       //std::vector <NewWindow> winds; // массив новых окон (дочерних)
       QVector  < NewWindow* > winds;
       QTextEdit * logEdit; // ссылка на edit, в который пишется журнал

        void logString(QString txt) //добавлет строку в edit
        {
            this->logEdit->setText((this->logEdit->toPlainText()+txt+"\n--------------\n"));
        }

 };

/* опишем класс
дополнительного окна

программы*/
class NewWindow :public QWidget
{ Q_OBJECT
   public:
        // храним ссылки на составные
    // компоненты - дочерние элементы окна
    QPushButton* button2;
    QPushButton* openNewWindow;
    QLineEdit*   pathEdit;
    QPushButton* startButton;
    QTextEdit *resultText;

    // храним ссылку на массив URL-ов
    // с информацией об их вхождениях в файлы
    ResultArray* resultInfo;//результат работы программы =))

// также сохраним ссылку на родительское окно чтобы
// обмениваться данными и посылать команды на создание дополнительных окон из главного окна
    myMainWindow* parentWindow; // ссылка на родителя

// далее описание конструктора дополнительного окна
    NewWindow(myMainWindow* parent,QString path="D:/Bu-Bu/HTML"): QWidget() //
    {

         /* ОЧЕНЬ ВАЖНО = чтобы виджеты отображались на дополнительном окне
         на хранить указатели на них в виде полей данного окна (его класса)
         как это сделано в данном примере,скажем, для кнопки  button2*/

       // this->parentWindow= parent; //запоминаем ссылку на родительское окно
        // обеспечим возможность передачи пути во внось открываемое окно

        this->parentWindow = parent;

        resultInfo = new ResultArray();

        this->resize(400, 500);
         // чтобы окна не были в куче используем qrand()
        this->move(100+(qrand() % 300), 100+(qrand() % 300));

        this->setWindowTitle("Окно операции (поиска)");


        pathEdit = new QLineEdit(path);
        pathEdit->setDragEnabled(1);

        button2 = new QPushButton("Выбрать директорию");
        button2->setToolTip("Нажмите чтобы выбрать директорию");
        button2->resize(button2->sizeHint());
       // button2->resize(150,60);


        startButton = new QPushButton("Поиск!");
        startButton->setToolTip("Нажмите чтобы начать поиск URL  в html файлах");
        startButton->resize(button2->sizeHint());
       // startButton->resize(150,60);

         openNewWindow = new QPushButton("Дополнительное окно");
         openNewWindow->setToolTip("Нажмите,чтобы открыть дополнительное окно");
         openNewWindow->resize(button2->sizeHint());
         //openNewWindow->resize(150,60);

        /*далее первые две цифры для каждого компонента -
    это номер ячейки с которой он "начинается" -  строка+ толбец -
    а вторые две - это насколько строк и столбцов он продливается*/

           QGridLayout *grid = new QGridLayout(this);
           grid->setSpacing(15);
           grid->addWidget(pathEdit, 0, 0, 1, 8);
           grid->addWidget(startButton, 1, 0, 1, 2);
           grid->addWidget(button2, 1, 2, 1, 3);
           grid->addWidget(openNewWindow, 1, 5, 1, 5);


          QLabel *review = new QLabel("Найдено:", this);
          grid->addWidget(review, 2, 0, 1, 1);

          resultText = new QTextEdit(this);
          grid->addWidget(resultText, 3, 0, 8, 8);

          setLayout(grid); //добавляем слой на виджет

          /*так как , вообще говоря данный метод - это конструтор
           * - то давайте прямо в нём же прикрепим
            слоты к сигналам*/

          // теперь при нажатии на кнопку с надвисью "Выбрать директорию"
          // будет появляться диалог выбора этой самой директории
          connect(button2, SIGNAL(clicked()),this, SLOT(chooseDirectory()));
          // поключаем возможность создания нового окна
          connect(openNewWindow, SIGNAL(clicked()),this, SLOT(openAdditionalWindow()));
          // подключаем поиск Url в файлах
           connect(startButton, SIGNAL(clicked()),this, SLOT(searchUrl()));

          this->show();

     }

    // пишем лог (обёртканад методом главоного окна)
    void logIt(QString str)
    {
        this->parentWindow->logString(str);//вызываем log-метод главного окна
    }

    //вернёт строчку, в которой окажется содержимое файла
    static QString readFile(QString filename)
    {
        QFile file(filename);
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
             return NULL;


        QByteArray total;
        QByteArray line;
        while (!file.atEnd()) {
           line = file.read(1024);
           total.append(line);
        }

        return QString(total);
     }

    /*проверяет - просматривая массив
      - известен ли нам уже данный URL*/
    int CheckUrlInArray(QString str,int strnumb,int colpoz, QString filename)
    {
        int result=0;
        UrlInfo* urlinfo;
       for (int i = 0; i < (int)this->resultInfo->urls.size(); ++i)
       {
           urlinfo =this->resultInfo->urls[i];
            if (urlinfo->url==str)
            {
                result=1;
                urlinfo->files.push_back(filename);
                urlinfo->col.push_back(colpoz);
                urlinfo->line.push_back(strnumb);

                break;
            }

        }
        return result;
    }
    /*проверяет известность URL-а - и если он не известен, то
     создаёт новую запист в массиве*/
    int IsInResultArray(QString str,int strnumb,int colpoz, QString filename)
    {
        int result=0;
        // если подобный url ещё не встречался
        if(!CheckUrlInArray(str,strnumb,colpoz,filename))
        {
            // создаём новую запись о новом Url-е
            UrlInfo* info= new UrlInfo();
            info->url=str;
            info->files.push_back(filename);
            info->col.push_back(colpoz);
            info->line.push_back(strnumb);
           result = 1;
            // добавляем эту запись в массива результата:
           this->resultInfo->urls.push_back(info);
        }
        return result; //нашли ли новый URL
    }

    int ParseString(QString str,int strnumb,QString filename)
    {

           int result=0;
          //QRegExp rxp("(http)") ; // (?:https?|ftp)://\\S+
           QRegExp rxp("((?:https?|ftp)://\\S+)"); // это далеко не лучшее выражение для URL.....))
         //  QRegExp rxp("^(http|https)://[a-z0-9]+([-.]{1}[a-z0-9]+)*.[a-z]{2,5}(([0-9]{1,5})?/?.*)$");
          // QRegExp rxp( "~^(?:(?:https?|ftp|telnet)://(?:[a-z0-9_-]{1,32}(?::[a-z0-9_-]{1,32})?@)?)?(?:(?:[a-z0-9-]{1,128}\.)+(?:ru|su|com|net|org|mil|edu|arpa|gov|biz|info|aero|inc|name|[a-z]{2})|(?!0)(?:(?!0[^.]|255)[0-9]{1,3}\.){3}(?!0|255)[0-9]{1,3})(?:/[a-z0-9.,_@%&?+=\~/-]*)?(?:#[^ '\"&]*)?$~i");

           //int pos = rxp->indexIn(str);
          //int pos = rxp.indexIn("Length: 36 inches");
          if (rxp.indexIn(str)!=-1) // если URL встречается в строке
          {
              QStringList list = rxp.capturedTexts(); // получаем массив вхождений
               QString rezline;
               for (int i = 0; i < (int)list.size(); ++i)
               {
                   result=1;
                   rezline = list[i];
                   QRegExp rxp("("+rezline+")");
                   int colnumb = rxp.indexIn(str);
                   if (colnumb)
                      result=(IsInResultArray(rezline,strnumb,colnumb,filename));

               }
          }
        return result;


    }
   // эта функция разбивает файл на строки и для каждой вызывает
    void ParseFile(QString str,QString filename)
    {
        QString line =""; // сюда заносим массив строк для каждого элемента
        QByteArray ar = str.toAscii();
        char* p=ar.data();
        int n1=0;
        int n=0;//счётчик строк
        int nu=0; // число найденных в файле уникальных URL
        while(*p)
        {

            if (*p=='\n')//если встретили символ переноса строки
            {  n++; // увеличиваем счётчик
               nu+=ParseString(line,n,filename); // отдаём строку на "разбор"
               line=""; // обнуляем временную строку
            } else
            {

                line+=*p; // прибавляем очередной символ
            }
            p++;
            if (line=="")// если была только одна строка
              {
                nu+=ParseString(line,n,filename); // отдаём строку на "разбор"
                n++;
              }
        }
        logIt("Найдено ["+QString::number(n) +"] строк" + "\n Среди них обнаружено ["+QString::number(nu) +"] уникальных URL");

    }

    void  ShowResult()
    {
        UrlInfo* urlinfo;
        QString result=""; // сюда записываем весь резульатат прежде чем вывести на экран
      //  foreach (this->resultInfo->urls,urlinfo)
        for (int i = 0; i < (int)this->resultInfo->urls.size(); ++i)
        {
            urlinfo=this->resultInfo->urls[i];
            result += "["+QString::number(i)+"] "+"URL ="+urlinfo->url+"\n встречается в файлах [строка] | [столбец] =\n";


            for (int j = 0; j < (int)urlinfo->files.size(); ++j)
            {
                result += "("+QString::number(j)+") Файл ="+urlinfo->files[j];
                result +=  " ["+QString::number(urlinfo->line[j])+"] | [";
                result +=QString::number(urlinfo->col[j])+"] =\n";
            }
            result +="\n=============================\n==========================\n";
        }
        this->resultText->setText(this->resultText->toPlainText()+result);// выводим результаты поиска на экран

    }

/*описываем слоты нашего окна операций(дочернее по отношению к главному)*/
public slots:
 void chooseDirectory() // описываем реализацию внутри тела программы
   {
     this->pathEdit->setText(QFileDialog::getExistingDirectory(this, tr("Open Directory"),"/home",QFileDialog::ShowDirsOnly));
   }
 void openAdditionalWindow() // описываем реализацию внутри тела программы
   {
     this->parentWindow->opnNewWindow(this->pathEdit->text());// используем  обычный метод
   }

 void searchUrl() // запускает функциию поиска вхождений Url
 {

    // получаем текущий путь и "открываем" папку
    QDir dir(this->pathEdit->text());// передаём в конструктор строку
    QStringList nameFilter; // имя фильтра
    // можно задать интересующие расширения nameFilter << "*.png" << "*.jpg" << "*.gif";
    nameFilter << "*.htm" << "*.html";// например такие
    QFileInfoList list = dir.entryInfoList( nameFilter, QDir::Files );// сказываем что нас интересуют только файлы

    QFileInfo fileinfo; // сюда будем считывать эжлементы
    foreach (fileinfo, list) // foreach - приятный подарок-макрос от Qt =)
    {
        logIt("Открыт файл = "+fileinfo.absoluteFilePath());
        ParseFile(readFile(fileinfo.absoluteFilePath()),fileinfo.absoluteFilePath());
        //this->resultText->setText(this->resultText->toPlainText()+readFile(fileinfo.absoluteFilePath())+"<br>");
    }

   //выводим результаты поиска в текстовое поле
   ShowResult();
 }


};


//===========далее описание методов и слотов для myMainWindow

void myMainWindow::openNewWindow() // описываем реализацию внутри тела программы
{
    NewWindow *  someNewWindow = new NewWindow(this); // Be sure to destroy you window somewhere
    winds.push_back(someNewWindow); // добавляем очедное окно -
    // наше приложение таким образом будет многооконным
}

void myMainWindow::opnNewWindow(QString path="123") // описываем реализацию снаружи (метод)
{
    NewWindow *  someNewWindow = new NewWindow(this,path); // Be sure to destroy you window somewhere
    winds.push_back(someNewWindow); // добавляем очедное окно -
    // наше приложение таким образом будет многооконным
}


// описываем конструктор снаружи класса
myMainWindow::myMainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /*создаём действие используя конструктор типа
    QAction ( const QString & text, QObject * parent )
    */
   QAction *quit2 = new QAction("&Quit", this);
   QMenu *file;
   file = menuBar()->addMenu("&File");
   // указываем одно из действий для элемента меню File


   QAction *newsearch = new QAction("&New search", this);

   file->addAction(newsearch);
   file->addAction(quit2);
   //file = menuBar()->addMenu("&File");

   /*прикрепляем сигналы к слотам - в обоих случаях мы оюидаем от пользователя
   активизации элемента меню (triggered())  - но для действия ВЫХОД
   мы вызываем стандартный слот выхода  =quit()
   а для действия открытия нового окна слот openNewWindow()
   котроый мы описали в классе    myMainWindow выше*/
   connect(quit2, SIGNAL(triggered()), qApp, SLOT(quit())); // для выхода
   connect(newsearch, SIGNAL(triggered()), this, SLOT(openNewWindow())); // для доп. окна

   this->setWindowTitle("Главное окно программы (4 задача Си++)");


   logEdit = new QTextEdit(this);
   logEdit->move(120,100);
   logEdit->resize(600,300);
   QLabel *review = new QLabel("Журнал событий:", this);
   review->move(10,100);
   this->resize(800, 400);
   this->show();


}

int main(int argc, char *argv[])
{
    // блок настройки кодировки
    // выбирайте кодировку в соответсвии с реальной кодировкой исходника
    QTextCodec *cyrillicCodec = QTextCodec::codecForName("UTF-8");
    QTextCodec::setCodecForTr(cyrillicCodec);
    QTextCodec::setCodecForLocale(cyrillicCodec);
    QTextCodec::setCodecForCStrings(cyrillicCodec);

    //конец блока настройки кодировки


     QApplication app ( argc,  argv );
     myMainWindow *window = new myMainWindow();

     return app.exec();

}
#include "main.moc"

vedro-compota's picture

#include "mainwindow.h"
#include
#include
#include
#include // для работы с кодировками

class UrlInfo
{
public:
QString url; // сам адрес
QVector files; // список файлов в которые он входит
QVector line;// строка вхождения
QVector col; // столбец вхождения

};

class ResultArray
{
public:
QVector urls; // массив с инфой о URL-ах

};

/*ниже дочерний и родительский класс взаимно используют друг друга в собственных
описаниях. Чтобы интерпретатор понял что к чему - мы сначала их объявляем
- а потом только описываем - причём методы
родительского класса описываем вообще снаружи - а первое объявлеение дочерего класса
- чисто формальное, оно позволяет интерпретатору понять,
что мы вообще имеем дело с классом (хотя бы это) а не со случайно
нажатой комбинацией клавишь =))
*/

class NewWindow;

/* опишем класс
главного окна который наследует
функционал и свойства QMainWindow*/

class myMainWindow:public QMainWindow
{ Q_OBJECT // макрос необходимый для вссякого класса
// который использует синтаксис Qt отличный от стандарта Си++
// -в нашем случае - это описание слотов Qt

public:
myMainWindow (QWidget *parent = 0); // описываем конструктор
//родитель по-умолчанию отсутствует

// тоже самое,что слот, только метод (для вызова из другого класса)
void opnNewWindow(QString path); // описываем реализацию снаружи

public slots:
void openNewWindow(); // реализацию слота опишем снаружи

public:
// хранит ссылку на второе(дополнительное)окно
// NewWindow *someNewWindow;
//std::vector winds; // массив новых окон (дочерних)
QVector winds;
QTextEdit * logEdit; // ссылка на edit, в который пишется журнал

void logString(QString txt) //добавлет строку в edit
{
this->logEdit->setText((this->logEdit->toPlainText()+txt+"\n--------------\n"));
}

};

/* опишем класс
дополнительного окна

программы*/
class NewWindow :public QWidget
{ Q_OBJECT
public:
// храним ссылки на составные
// компоненты - дочерние элементы окна
QPushButton* button2;
QPushButton* openNewWindow;
QLineEdit* pathEdit;
QPushButton* startButton;
QTextEdit *resultText;

// храним ссылку на массив URL-ов
// с информацией об их вхождениях в файлы
ResultArray* resultInfo;//результат работы программы =))

// также сохраним ссылку на родительское окно чтобы
// обмениваться данными и посылать команды на создание дополнительных окон из главного окна
myMainWindow* parentWindow; // ссылка на родителя

// далее описание конструктора дополнительного окна
NewWindow(myMainWindow* parent,QString path="D:/Bu-Bu/HTML"): QWidget() //
{

/* ОЧЕНЬ ВАЖНО = чтобы виджеты отображались на дополнительном окне
на хранить указатели на них в виде полей данного окна (его класса)
как это сделано в данном примере,скажем, для кнопки button2*/

// this->parentWindow= parent; //запоминаем ссылку на родительское окно
// обеспечим возможность передачи пути во внось открываемое окно

this->parentWindow = parent;

resultInfo = new ResultArray();

this->resize(400, 500);
// чтобы окна не были в куче используем qrand()
this->move(100+(qrand() % 300), 100+(qrand() % 300));

this->setWindowTitle("Окно операции (поиска)");

pathEdit = new QLineEdit(path);
pathEdit->setDragEnabled(1);

button2 = new QPushButton("Выбрать директорию");
button2->setToolTip("Нажмите чтобы выбрать директорию");
button2->resize(button2->sizeHint());
// button2->resize(150,60);

startButton = new QPushButton("Поиск!");
startButton->setToolTip("Нажмите чтобы начать поиск URL в html файлах");
startButton->resize(button2->sizeHint());
// startButton->resize(150,60);

openNewWindow = new QPushButton("Дополнительное окно");
openNewWindow->setToolTip("Нажмите,чтобы открыть дополнительное окно");
openNewWindow->resize(button2->sizeHint());
//openNewWindow->resize(150,60);

/*далее первые две цифры для каждого компонента -
это номер ячейки с которой он "начинается" - строка+ толбец -
а вторые две - это насколько строк и столбцов он продливается*/

QGridLayout *grid = new QGridLayout(this);
grid->setSpacing(15);
grid->addWidget(pathEdit, 0, 0, 1, 8);
grid->addWidget(startButton, 1, 0, 1, 2);
grid->addWidget(button2, 1, 2, 1, 3);
grid->addWidget(openNewWindow, 1, 5, 1, 5);

QLabel *review = new QLabel("Найдено:", this);
grid->addWidget(review, 2, 0, 1, 1);

resultText = new QTextEdit(this);
grid->addWidget(resultText, 3, 0, 8, 8);

setLayout(grid); //добавляем слой на виджет

/*так как , вообще говоря данный метод - это конструтор
* - то давайте прямо в нём же прикрепим
слоты к сигналам*/

// теперь при нажатии на кнопку с надвисью "Выбрать директорию"
// будет появляться диалог выбора этой самой директории
connect(button2, SIGNAL(clicked()),this, SLOT(chooseDirectory()));
// поключаем возможность создания нового окна
connect(openNewWindow, SIGNAL(clicked()),this, SLOT(openAdditionalWindow()));
// подключаем поиск Url в файлах
connect(startButton, SIGNAL(clicked()),this, SLOT(searchUrl()));

this->show();

}

// пишем лог (обёртканад методом главоного окна)
void logIt(QString str)
{
this->parentWindow->logString(str);//вызываем log-метод главного окна
}

//вернёт строчку, в которой окажется содержимое файла
static QString readFile(QString filename)
{
QFile file(filename);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return NULL;

QByteArray total;
QByteArray line;
while (!file.atEnd()) {
line = file.read(1024);
total.append(line);
}

return QString(total);
}

int CheckColAndLine(int elnumd,int col,int line,QString filename)
{
int result = 0;//такого вхождения нет
UrlInfo* urlinfo = this->resultInfo->urls[elnumd];
for (int i = 0; i files.size(); ++i)
{
if ((urlinfo->line[i]==line)&&(urlinfo->col[i]==col)&&(!(QString::compare(urlinfo->files[i],filename))))
{
result=1;
}
}
return result;
}

/*проверяет - просматривая массив
- известен ли нам уже данный URL*/
int CheckUrlInArray(QString str,int strnumb,int colpoz, QString filename)
{
int result=0;
UrlInfo* urlinfo;
for (int i = 0; i resultInfo->urls.size(); ++i)
{
urlinfo =this->resultInfo->urls[i];
if (!(QString::compare(urlinfo->url,str)))// если такой URL уже известен
{
result=1;
/*решаем - записывать и очередное вхождение*/
if (!(CheckColAndLine(i,colpoz,strnumb,filename))) // если это другая строка или другое вхождение на этой же строке
{
urlinfo->files.push_back(filename);
urlinfo->col.push_back(colpoz);
urlinfo->line.push_back(strnumb);
}
break;
}

}
return result;
}
/*проверяет известность URL-а - и если он не известен, то
создаёт новую запист в массиве*/
int IsInResultArray(QString str,int strnumb,int colpoz, QString filename)
{
int result=0;
// если подобный url ещё не встречался
if(!CheckUrlInArray(str,strnumb,colpoz,filename))
{
// создаём новую запись о новом Url-е
UrlInfo* info= new UrlInfo();
info->url=str;
info->files.push_back(filename);
info->col.push_back(colpoz);
info->line.push_back(strnumb);
// добавляем эту запись в массива результата:
this->resultInfo->urls.push_back(info);

result = 1;// фиксируем тот факт, что нашли новый
}

return result; //нашли ли новый URL
}

int ParseString(QString str,int strnumb,QString filename)
{

int result=0;
//QRegExp rxp("(http)") ; // (?:https?|ftp)://\\S+
QRegExp rxp("((?:https?|ftp)://\\S+)"); // это далеко не лучшее выражение для URL.....))
// QRegExp rxp("^(http|https)://[a-z0-9]+([-.]{1}[a-z0-9]+)*.[a-z]{2,5}(([0-9]{1,5})?/?.*)$");
// QRegExp rxp( "~^(?:(?:https?|ftp|telnet)://(?:[a-z0-9_-]{1,32}(?::[a-z0-9_-]{1,32})?@)?)?(?:(?:[a-z0-9-]{1,128}\.)+(?:ru|su|com|net|org|mil|edu|arpa|gov|biz|info|aero|inc|name|[a-z]{2})|(?!0)(?:(?!0[^.]|255)[0-9]{1,3}\.){3}(?!0|255)[0-9]{1,3})(?:/[a-z0-9.,_@%&?+=\~/-]*)?(?:#[^ '\"&]*)?$~i");

//int pos = rxp->indexIn(str);
//int pos = rxp.indexIn("Length: 36 inches");
if (rxp.indexIn(str)!=-1) // если URL встречается в строке
{
QStringList list = rxp.capturedTexts(); // получаем массив вхождений
QString rezline;
for (int i = 0; i {

rezline = list[i];
QRegExp rxp("("+rezline+")");
int colnumb = rxp.indexIn(str);
if (colnumb!=-1)
result+=(IsInResultArray(rezline,strnumb,colnumb,filename));

}
}
return result;

}
// эта функция разбивает файл на строки и для каждой вызывает
void ParseFile(QString str,QString filename)
{
QString line =""; // сюда заносим массив строк для каждого элемента
QByteArray ar = str.toAscii();
char* p=ar.data();
int n1=0;
int n=0;//счётчик строк
int nu=0; // число найденных в файле уникальных URL
while(*p)
{

if (*p=='\n')//если встретили символ переноса строки
{ n++; // увеличиваем счётчик
nu+=ParseString(line,n,filename); // отдаём строку на "разбор"
line=""; // обнуляем временную строку
} else
{

line+=*p; // прибавляем очередной символ
}
p++;
if (line=="")// если была только одна строка
{
nu+=ParseString(line,n,filename); // отдаём строку на "разбор"
n++;
}
}
logIt("Найдено ["+QString::number(n) +"] строк" + "\n Среди них обнаружено ["+QString::number(nu) +"] уникальных URL");

}

void ShowResult()
{
UrlInfo* urlinfo;
QString result=""; // сюда записываем весь резульатат прежде чем вывести на экран
// foreach (this->resultInfo->urls,urlinfo)
for (int i = 0; i resultInfo->urls.size(); ++i)
{
urlinfo=this->resultInfo->urls[i];
result += "["+QString::number(i)+"] "+"URL ="+urlinfo->url+"\n встречается в файлах [строка] | [столбец] =\n";

for (int j = 0; j files.size(); ++j)
{
result += "("+QString::number(j)+") Файл ="+urlinfo->files[j];
result += " ["+QString::number(urlinfo->line[j])+"] | [";
result +=QString::number(urlinfo->col[j])+"] =\n";
}
result +="\n=============================\n==========================\n";
}
this->resultText->setText(this->resultText->toPlainText()+result);// выводим результаты поиска на экран

}

/*описываем слоты нашего окна операций(дочернее по отношению к главному)*/
public slots:
void chooseDirectory() // описываем реализацию внутри тела программы
{
this->pathEdit->setText(QFileDialog::getExistingDirectory(this, tr("Open Directory"),"/home",QFileDialog::ShowDirsOnly));
}
void openAdditionalWindow() // описываем реализацию внутри тела программы
{
this->parentWindow->opnNewWindow(this->pathEdit->text());// используем обычный метод
}

void searchUrl() // запускает функциию поиска вхождений Url
{

// получаем текущий путь и "открываем" папку
QDir dir(this->pathEdit->text());// передаём в конструктор строку
QStringList nameFilter; // имя фильтра
// можно задать интересующие расширения nameFilter nameFilter QFileInfoList list = dir.entryInfoList( nameFilter, QDir::Files );// сказываем что нас интересуют только файлы

QFileInfo fileinfo; // сюда будем считывать эжлементы
foreach (fileinfo, list) // foreach - приятный подарок-макрос от Qt =)
{
logIt("Открыт файл = "+fileinfo.absoluteFilePath());
ParseFile(readFile(fileinfo.absoluteFilePath()),fileinfo.absoluteFilePath());
//this->resultText->setText(this->resultText->toPlainText()+readFile(fileinfo.absoluteFilePath())+"
");
}

//выводим результаты поиска в текстовое поле
ShowResult();
}

};

//===========далее описание методов и слотов для myMainWindow

void myMainWindow::openNewWindow() // описываем реализацию внутри тела программы
{
NewWindow * someNewWindow = new NewWindow(this); // Be sure to destroy you window somewhere
winds.push_back(someNewWindow); // добавляем очедное окно -
// наше приложение таким образом будет многооконным
}

void myMainWindow::opnNewWindow(QString path="123") // описываем реализацию снаружи (метод)
{
NewWindow * someNewWindow = new NewWindow(this,path); // Be sure to destroy you window somewhere
winds.push_back(someNewWindow); // добавляем очедное окно -
// наше приложение таким образом будет многооконным
}

// описываем конструктор снаружи класса
myMainWindow::myMainWindow(QWidget *parent)
: QMainWindow(parent)
{
/*создаём действие используя конструктор типа
QAction ( const QString & text, QObject * parent )
*/
QAction *quit2 = new QAction("&Quit", this);
QMenu *file;
file = menuBar()->addMenu("&File");
// указываем одно из действий для элемента меню File

QAction *newsearch = new QAction("&New search", this);

file->addAction(newsearch);
file->addAction(quit2);
//file = menuBar()->addMenu("&File");

/*прикрепляем сигналы к слотам - в обоих случаях мы оюидаем от пользователя
активизации элемента меню (triggered()) - но для действия ВЫХОД
мы вызываем стандартный слот выхода =quit()
а для действия открытия нового окна слот openNewWindow()
котроый мы описали в классе myMainWindow выше*/
connect(quit2, SIGNAL(triggered()), qApp, SLOT(quit())); // для выхода
connect(newsearch, SIGNAL(triggered()), this, SLOT(openNewWindow())); // для доп. окна

this->setWindowTitle("Главное окно программы (4 задача Си++)");

logEdit = new QTextEdit(this);
logEdit->move(120,100);
logEdit->resize(600,300);
QLabel *review = new QLabel("Журнал событий:", this);
review->move(10,100);
this->resize(800, 400);
this->show();

}

int main(int argc, char *argv[])
{
// блок настройки кодировки
// выбирайте кодировку в соответсвии с реальной кодировкой исходника
QTextCodec *cyrillicCodec = QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForTr(cyrillicCodec);
QTextCodec::setCodecForLocale(cyrillicCodec);
QTextCodec::setCodecForCStrings(cyrillicCodec);

//конец блока настройки кодировки

QApplication app ( argc, argv );
myMainWindow *window = new myMainWindow();

return app.exec();

}
#include "main.moc"

_____________
матфак вгу и остальная классика =)