Помощь с QThread [закрыт]

254
17 января 2019, 17:20

Не уверен, что вопрос корректен по правилам форума. Но совсем в тупике.

Есть много уроков, читал/смотрел как русские, как и иноязычные. Но никак не могу разобраться с этим синтаксисом QThread. Повторял проекты, они работали, но как натыкаюсь на свой - ступор.

Есть условно три функции:

  • Загрузить файлы
  • Отсортировать файлы
  • Записать файлы на диск в отсортированном виде

Каждая задача на отдельной кнопке в mainwindow.

Сама реализация работает, осталось сделать так, чтоб программа не висла при большом объёме файлов.

Итак, я знаю, что можно определить класс, уноследовать его от QThread, подключить сигналы к слотам.. Вот тут проблема номера раз.. Переопределять несолько методов run()? Здравый смысл говорит, что метод я могу назвать как угодно, и даже (обоже) сделать три метода на каждую свою задачу. Так ли это? Или что, по одному классу на каждую задачу?? (Метод без переопределения run() тоже видел, но там ещё более мутно..)

Дальше, опять же с конектом (QT5).. Что куда?

Я не прошу решить задачу за меня, так что и код кидать не вижу смысла. Но если есть время, пожалуйста, распишите хоть простенькую схему на моей задаче "что-как-куда". Может так я въеду..

Answer 1

Наследовать от QThread не нужно. Нужно создать класс на базе QObject. Т.к. в вашей задаче 3 этапа, то нужно 3 слота и 3 сигнала.

class QWorker : public QObject
{
    Q_OBJECT
public:
    QWorker(QObject *parent):QObject(parent){инициализация класса}
public slots:
    void step1(){Шаг 1; emit step1Finish();}
    void step2(){Шаг 2; emit step2Finish();};
    void step3(){Шаг 3; emit step3Finish();};
signals:
    step1Finish();
    step2Finish();
    step3Finish();
};

Теперь поместим наш объект в отдельный поток. На самом деле объект никуда не перемещается, просто для потока создается еще одна очередь обработки сообщений и сигналы, направленные к этому объекту, будут обрабатываться отдельной очередью в отдельном потоке.

QWorker *worker = new QWorker();
QThread thread* = new QThread();
worker->moveToThread(thread);
//Теперь обработка слотов, запущенных сигналом пойдет в отдельном потоке
thread->start();
//Запускаем цикл обработки событий в отдельном потоке

В вашем примере задачи выполняются последовательно, поэтому в форме выключаем кнопки 2 и 3 и цепляем сигналы вот так

connect(button1, SIGNAL(clicked()), worker, SLOT(step1()));
connect(button1, SIGNAL(clicked()), button1, SLOT(setDisabled()));
connect(worker, SIGNAL(step1Finish()), button2, SLOT(setEnabled()));
connect(button2, SIGNAL(clicked()), worker, SLOT(step2()));
connect(button2, SIGNAL(clicked()), button2, SLOT(setDisabled()));
connect(worker, SIGNAL(step2Finish()), button3, SLOT(setEnabled()));
connect(button3, SIGNAL(clicked()), worker, SLOT(step3()));
connect(button3, SIGNAL(clicked()), button3, SLOT(setDisabled()));

Теперь программа будет работать так:

Жмем кнопку1 - запускается шаг1 и выключается кнопка1

Шаг1 завершен, включается кнопка2

Жмем кнопку2 - запускается шаг2 и выключается кнопка2

Шаг2 завершен, включается кнопка3

Жмем кнопку3 - запускается шаг3 и выключается кнопка3

После завершения генерируется сигнал step3Finish() и тут вам решать, что делать дальше. Но нужно не забыть остановить thread т.к. он все равно ни чем не занят. Для этого, после помещения worker в отдельный поток можно сделать так

connect(worker, SIGNAL(step3Finish()), thread, SLOT(quit()));

Теперь после выполнения шага3 поток будет завершаться.

Answer 2

1) Наследоваться от QThread - неправильно. Наследование нужно в случае, когда на базе класса создаётся другой, с дополнительным функционалом. QThread является обёрткой, которая и так уже содержит всё, что нужно для работы с потоками.

2) Возможно, нет необходимости работать с потоками вручную. Весь QtLib уже работает на потоках, в которых обрабатываются сигналы и в некоторых случаях с подвисаниями помогает вызов QApplication::processEvents() в нужном месте.

READ ALSO
Как сделать bean видимым во всех страницах jsp

Как сделать bean видимым во всех страницах jsp

есть 2 части страницы headjsp и footer

212
Браузер для java [закрыт]

Браузер для java [закрыт]

Подскажите библиотеку-браузер для java, которая может отрабатывать javascriptИли возможность взаимодействия java с существующим браузером

250
Как работает JVM написанная на Java?

Как работает JVM написанная на Java?

Объясните, недалекомуДля запуска Java приложений требуется JVM

269