Russian Qt Forum
Май 02, 2024, 12:26 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QprogressBar в отдельном потоке!  (Прочитано 17543 раз)
kadr
Гость
« : Август 27, 2010, 13:24 »

Привет всем! Помогите разобраться с проблемой!
Мне надо что бы копировании файла,  прогрессбар отображал ход выполнения копирования!
Из найденого в интернете:
Создаю класс:
Код:
class MyThread : public QThread
{
public:
virtual void run();

};

Далее в программе создаю виджет с размещенными на нем метками и прогрессбарами:
Код:
void Linux_Comander::progress_bar(QString begin_path, QString end_path)
{
    MyThread run;


    QWidget *dialog_progress = new QWidget;
    progres = new QProgressBar(this);
    progres_all = new QProgressBar(this);

    QVBoxLayout *main_layt = new QVBoxLayout;
    QVBoxLayout *progress = new QVBoxLayout;
    QVBoxLayout *progress_all = new QVBoxLayout;
    QVBoxLayout *path_l = new QVBoxLayout;
    QVBoxLayout *path_r = new QVBoxLayout;
    QHBoxLayout *buttons = new QHBoxLayout;
    QLabel *path = new QLabel;
    QLabel *path_f = new QLabel;

    QPushButton *button_cancel = new QPushButton;

    button_cancel->setText("Закрыть");
    button_cancel->setFont(QFont("",8,72,false));

    buttons->addWidget(button_cancel);
    buttons->setContentsMargins(150,1,150,1);

    progres->setAlignment(Qt::AlignHCenter);
    progres_all->setAlignment(Qt::AlignHCenter);

    progress->addWidget(progres);
    progress_all->addWidget(progres_all);

    path_l->addWidget(path);
    path_r->addWidget(path_f);

    main_layt->addLayout(path_l);
    main_layt->addLayout(path_r);
    main_layt->addLayout(progress);
    main_layt->addLayout(progress_all);
    main_layt->addLayout(buttons);



    dialog_progress->setGeometry((x/2)-(450/2),(y/2)-(150/2),450,150);
    dialog_progress->setWindowModality(Qt::ApplicationModal);
    dialog_progress->setStyleSheet("background-color: #CCCCCF");
    dialog_progress->setWindowTitle("Копирование");
    dialog_progress->setFixedSize(450,150);
    dialog_progress->setLayout(main_layt);
    dialog_progress->show();


    path->setText(begin_path);
    path_f->setText(end_path);

    QFile file,f;

    file.setFileName(model_l->filePath(ui->left_pole->currentIndex()));
    file.open(QIODevice::ReadOnly);
    f.setFileName(line_finish->text()+"/"+model_l->fileName(ui->left_pole->currentIndex()));
    f.open(QIODevice::WriteOnly);

    progres->setMaximum(file.size());


    while (!file.atEnd())
    {
        f.write(file.readLine());
        run.start(QThread::HighPriority);
        run.wait();

    }
    connect(button_cancel,SIGNAL(clicked()),dialog_progress,SLOT(close()));

}
Здесь я построчно копирую файл, и вызываю новый поток!
Код:
void MyThread::run()
{
    qDebug() << "asdasd";

}
Так вот собствено проблема в том, что я не знаю как передовать в поток нужные мне переменные?
Мне надо что бы на прогрессбаре отображался ход копирования, и при этом не вешалось главное окно!
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #1 : Август 27, 2010, 13:57 »

На пример. В аттаче.

Процесс копирования ты должен делать в потоке Run! т.е. там где в примере цикл forever.
« Последнее редактирование: Август 27, 2010, 14:01 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
kadr
Гость
« Ответ #2 : Август 27, 2010, 14:37 »

На пример. В аттаче.

Процесс копирования ты должен делать в потоке Run! т.е. там где в примере цикл forever.
Все это хорошо, а как туда передовать параметры? Например что копировать и куда копировать.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #3 : Август 27, 2010, 15:17 »


*.h
Код:
class Thread : public QThread
{
    Q_OBJECT

signals:
    void signalForProgressBar(int);
public:
    Thread(const QString &copyFrom, const QString &copyTo, QObject *parent = 0);
    ~Thread();
protected:
    void run();
private:
    QString m_from;
    QString m_to;
};

*.cpp
Код:
Thread::Thread(const QString &copyFrom, const QString &copyTo, QObject *parent)
    : QThread(parent), m_from(copyFrom), m_to(copyTo)
{
}

Thread::~Thread()
{

}

void Thread::run()
{
    //тут копируешь, у тебя есть откуда копировать m_from и куда m_to
    //по мере копирования эммитиш сигнал   emit signalForProgressBar(i);

}
Записан

ArchLinux x86_64 / Win10 64 bit
kadr
Гость
« Ответ #4 : Сентябрь 01, 2010, 10:03 »

Впринципе файл копируется но окно в котором должен отображаться ход процесса копирования, то есть где прогресс бар, оно зависает на время копирования, на нем ничего не видно. Да и как мне передовать ход выполнения копирования на прогресс бар, то есть, что бы он заполнялся.
Получается что копирование запускается в отдельном потоке, а основной поток в котором создается диалоговое окно с барами оно ждет выполнения - завершения потока копирования

Код:
void Linux_Comander::progress_bar(QString begin_path, QString end_path)//функция отображения хода копирования
{


//динамическое создание диалога со всем небходимым
    QWidget *dialog_progress = new QWidget;//основной виджет
    QProgressBar *progres = new QProgressBar;//прогресс бар первый
    QProgressBar *progres_all = new QProgressBar;//прогресс бар общий

    QVBoxLayout *main_layt = new QVBoxLayout;//вертикальный лаут
    QVBoxLayout *progress = new QVBoxLayout;//вертикальный лаут
    QVBoxLayout *progress_all = new QVBoxLayout;//вертикальный лаут
    QVBoxLayout *path_l = new QVBoxLayout;//вертикальный лаут
    QVBoxLayout *path_r = new QVBoxLayout;//вертикальный лаут
    QHBoxLayout *buttons = new QHBoxLayout;//горизонтальный лаут
    QLabel *path = new QLabel;//лайблы
    QLabel *path_f = new QLabel;//

    QPushButton *button_cancel = new QPushButton;//кнопка

    button_cancel->setText("Закрыть");//текст на кнопке
    button_cancel->setFont(QFont("",8,72,false));//шрифт на кнопке

    buttons->addWidget(button_cancel);//присваеваем лауту виджет кнопки
    buttons->setContentsMargins(150,1,150,1);//установливаем поля

    progres->setAlignment(Qt::AlignHCenter);//выравниваем текст на прогресс баре посередине
    progres_all->setAlignment(Qt::AlignHCenter);//на втором тоже

    progress->addWidget(progres);//присваиваем лауту виджет пргресс бара
    progress_all->addWidget(progres_all);//и воторого то же

    path_l->addWidget(path);//присваиваем лауту виджет лабла
    path_r->addWidget(path_f);//и второго
    //присваиваем основному лауту все лауты
    main_layt->addLayout(path_l);
    main_layt->addLayout(path_r);
    main_layt->addLayout(progress);
    main_layt->addLayout(progress_all);
    main_layt->addLayout(buttons);



    dialog_progress->setGeometry((x/2)-(450/2),(y/2)-(150/2),450,150);//устанавливаем диалог в центре экрана
    dialog_progress->setWindowModality(Qt::ApplicationModal);//делаем окно модальным
    dialog_progress->setStyleSheet("background-color: #CCCCCF");//цвет диалога
    dialog_progress->setWindowTitle("Копирование");//заголовок
    dialog_progress->setFixedSize(450,150);//фиксированый размер
    dialog_progress->setLayout(main_layt);//ресайз основного лаута
    dialog_progress->show();//показываем его


    path->setText("Из: "+begin_path);//лайблам присваиваем текст
    path_f->setText("В: "+end_path);//второму тоже


    MyThread(str.trimmed(),str1.trimmed(),0).start(QThread::HighPriority);// запускает второй поток в котором происходит копирование файлов

    connect(button_cancel,SIGNAL(clicked()),dialog_progress,SLOT(close()));//при нажатии на кнопку закрыть, закрыть диалог

}


Код:
MyThread::MyThread(const QString &copyFrom, const QString &copyTo, QObject *parent)
    : QThread(parent), m_from(copyFrom), m_to(copyTo)
{

  
}

void MyThread::run()
{


    QFile file,f;
    int i = 0;

               file.setFileName(m_from);//присваеваем переменной file имя файла на диске
               qDebug() << file.fileName();
               qDebug() << file.open(QIODevice::ReadOnly);//открываем его на чтение

               f.setFileName(m_to);//аналогично предыдущему
               qDebug() << f.fileName();
               qDebug() << f.open(QIODevice::WriteOnly);//на запись


               while (!file.atEnd())//запускаем цикл в котором файл копируется построчно
                {
                  
                   f.write(file.readLine());//построчное записывание
                   emit signalForProgressBar(i);

                   i++;
                }

}

MyThread::~MyThread()
{
    if (!isRunning())
        return;

    wait();
}
« Последнее редактирование: Сентябрь 01, 2010, 10:17 от kadr » Записан
RedDog
Гость
« Ответ #5 : Сентябрь 01, 2010, 14:04 »

Впринципе файл копируется но окно в котором должен отображаться ход процесса копирования, то есть где прогресс бар, оно зависает на время копирования, на нем ничего не видно. Да и как мне передовать ход выполнения копирования на прогресс бар, то есть, что бы он заполнялся.
Создай слот в диалоге, на который будет приходить сигнал от потока с параметром выполнения.

Код:
void MyWindow::on_progress(int progress)
{
    ui->progressBar->setValue(progress);
}
предварительно связав его с сигналом от потока:

Код:
connect(CopyProgress, SIGNAL(progress(int)), this, SLOT(on_progress(int)));
где CopyProgress - указатель на экземпляр объекта потока копирования
Код:
SIGNAL(progress(int))
- его сигнал о проценте выполнения.
Записан
kadr
Гость
« Ответ #6 : Сентябрь 01, 2010, 15:32 »

короче виснет, я не понял где connect нужно прописывать. Я прописал в финкции которая создает диалог.
Код:
...
path->setText("Из: "+begin_path);//лайблам присваиваем текст
    path_f->setText("В: "+end_path);//второму тоже
    MyThread *tr;
    
    connect (tr,SIGNAL(signalForProgressBar(int)),this,SLOT(progress_signal(int)));

    MyThread(begin_path.trimmed(),end_path.trimmed()).start(QThread::HighPriority);// запускает второй поток в котором отображается ход копирования
    
    connect(button_cancel,SIGNAL(clicked()),dialog_progress,SLOT(close()));//при нажатии на кнопку закрыть, закрыть диалог
сделал вот так
Код:
path->setText("Из: "+begin_path);//лайблам присваиваем текст
    path_f->setText("В: "+end_path);//второму тоже
    MyThread *tr = new MyThread(begin_path.trimmed(),end_path.trimmed());

    connect (tr,SIGNAL(signalForProgressBar(int)),this,SLOT(progress_signal(int)));

    //MyThread(begin_path.trimmed(),end_path.trimmed()).start(QThread::HighPriority);// запускает второй поток в котором отображается ход копирования
    tr->start(QThread::HighPriority);
   
    connect(button_cancel,SIGNAL(clicked()),dialog_progress,SLOT(close()));//при нажатии на кнопку закрыть, закрыть диалог
выводит диалог и даже заполняется бар, очень быстро и файл не полностью копируется, когда начинаешь копировать следующий, докачивается предыдущий, а следующий не копируется вообще, это как понимать?
« Последнее редактирование: Сентябрь 01, 2010, 15:40 от kadr » Записан
RedDog
Гость
« Ответ #7 : Сентябрь 01, 2010, 15:48 »

пример:
Записан
kadr
Гость
« Ответ #8 : Сентябрь 03, 2010, 14:35 »

сделал все как написано в файле, и не пойму что ему, от меня надо, не хочет компилиться и все!

Код:
no matching function for call to 'progress_view::progress_view()'
progress_view.h
Код:
#ifndef PROGRESS_VIEW_H
#define PROGRESS_VIEW_H

#include "QThread"
#include "QFile"

class progress_view : public QThread
{
    Q_OBJECT

signals:
    void on_progress(int progress);

public:
    explicit progress_view(const QString &copyFrom, const QString &copyTo, QObject *parent = 0);


    QString m_from,m_to;

protected:
    void run();


};

#endif // PROGRESS_VIEW_H
progress_view.cpp
Код:
#include "progress_view.h"

progress_view::progress_view(const QString &copyFrom, const QString &copyTo, QObject *parent)
    : QThread(parent), m_from(copyFrom), m_to(copyTo)
{
}
void progress_view::run()
{
    QFile file,f;
    int i = 0;

               file.setFileName(m_from);//присваеваем переменной file имя файла на диске

               file.open(QIODevice::ReadOnly);//открываем его на чтение

               f.setFileName(m_to);//аналогично предыдущему

               f.open(QIODevice::WriteOnly);//на запись


               while (!file.atEnd())//запускаем цикл в котором файл копируется построчно
                {
                   f.write(file.readLine());//построчное записывание
                   emit on_progress(i);
                   i++;
                }

    exec();
}
Linux_Comander.cpp связывания сигнала со слотом в конструкторе класса!
Код:
Linux_Comander::Linux_Comander(QWidget *parent) :
    QMainWindow(parent),ui(new Ui::Linux_Comander)
{
    ui->setupUi(this);

    connect(&p_bar,SIGNAL(on_progress(int)),this,SLOT(progress_signal(int)));

...
Linux_Comander.cpp  передача переменных в progress_view и запуск потока!
Код:
progress_view(begin_path,end_path,0);

    p_bar.start();

Если передавать без параметров explicit progress_view(QObject *parent = 0);, то нормально отрабатывает, только мне надо обязательно передавать пути копирования.
« Последнее редактирование: Сентябрь 03, 2010, 15:02 от kadr » Записан
RedDog
Гость
« Ответ #9 : Сентябрь 03, 2010, 15:02 »

чего в ошибках выдает?
Записан
kadr
Гость
« Ответ #10 : Сентябрь 03, 2010, 15:45 »

сейчас сделал по другому, передаю параметры по другому
 p_bar.m_from=begin_path;
 p_bar.m_to=end_path;
 p_bar.start();
Запускается нормально, но при копировании ведет себя не правильно, прогресс бар не заполняется, и файл не копируется, программа после завершения еще остается висеть в процессах.
Записан
RedDog
Гость
« Ответ #11 : Сентябрь 03, 2010, 23:53 »

держи
Записан
Blackwanderer
Гость
« Ответ #12 : Сентябрь 04, 2010, 07:24 »

Может быть вас заинтересует класс QProgressDialog...
Записан
kadr
Гость
« Ответ #13 : Сентябрь 08, 2010, 08:40 »

Попробывал QProgressDialog, да работать с ним легче и понятнее. только вот возник один вопрос.
Я использую QFileSystemModel для отображения файловой системы, так вот после того, как файл скопировался, его размер отображается как нулевой, если скопировать или удалить какой нибудь файл то показывается нормальный размер, как сделать что бы после того как файл скопировался, дерево обновлялось?

Код:
 model_l = new QFileSystemModel(this);
   model_r = new QFileSystemModel(this);

   model_l->setRootPath("C:/");
   model_r->setRootPath("D:/");

   ui->left_pole->setModel(model_l);//установка qtreeview в соответствиис моделью.
   ui->right_pole->setModel(model_r);
Записан
kadr
Гость
« Ответ #14 : Сентябрь 09, 2010, 08:10 »

Привет всем, подскажите, как в QTreeView можно изменить цвет текста в текущем итеме? Мне нужно что бы при нажатии кнопки, допустим insert, как в тотале, текищий элемент выделялся красным цветом, и курсор смещался вниз на одну позицию.  Непонимающий
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.142 секунд. Запросов: 22.