Снова потоки, как правильно запустить и остановить поток?

371
27 октября 2017, 13:35

Перепрочитал мануал к qt, а так же прошестел столько сколько смог.

Приложение, в котором интерфейс реализован с помощью qml в среде QtCreator. Для передачи параметров воспользовался следующим способом, объявленным в главном методе Main:

QQuickView viewer;
deviceScaner=new scaner;
viewer.rootContext()->setContextProperty("deviceScaner",deviceScaner);

Далее из Qml вызываю напрямую методы deviceScaner(**Type** paramethr). Класс сканер реализован в отдельных файлах (интерфейс и реализация).

Задача следующая: есть устройство, которое с большой частотой шлет данные для визуализации. Пробовал по-разному передать метод в поток, класс в поток (через MoveToThread), результат - либо ошибка при сборке, либо зависание. Необходимо отрисовывать данные как можно быстрее (за это отвечает один метод который достает из области памяти эти данные) так, чтобы весь остальной интерфейс был рабочий и отзывчивый.

Не могу понять где создавать объект потока, а так же где и как правильно передавать параметры в него, с учетом того что интерфейс на qtquick.

Answer 1

Я делаю следующим образом. Отдельный класс как посредник между интерфейсом и классами функционала. Отдельный класс для создания потока-обертки взят из Хабрахабра. По ссылке довольно подробно расписано.

В Main.cpp я использую другой метод:

QQmlApplicationEngine engine;
QObject *root = engine.rootObjects()[0];
Foo *foo= new Foo(root); //класс-посредник

Соответственно в классе Foo интерфейс привязывается следующим образом:

Foo::Foo(QObject *parent) : QObject(parent)
{
    root = parent; //указатель на интерфейс
}

В заголовочном файле не забудьте создать QObject *root;

Данные между qml-интерфейсом и классами на С++ можно передавать разными способами. Я использую сигналы и слоты. В qml создаётся сигнал, например signal qmlLoad(string file), когда надо, вы его вызываете. В классе посреднике вы его соединяете следующим образом:

connect(root, SIGNAL(qmlLoad(QString)), this, SLOT(someLoad(QString)));

Для связи с потоком тоже ничего сложного. Вот передача строки от потока в интерфейс(прописывается в том же классе, где создаются потоки. В моём случае это класс-посредник):

connect(*_obj, SIGNAL(iniReady(QString)), root, SIGNAL(iniReady(QString)));

А в его обработка вызывается очень просто:

signal iniReady(string name)
onIniReady: {
        for (var i = 0; i < loaderModel.count; i++) {
            if (loaderModel.get(i).name === name) {
                loaderModel.setProperty("number", i)
                break
            }
        }
    }
READ ALSO
Безопасность функции pop() у контейнера

Безопасность функции pop() у контейнера

Трудно сделать безопасной функцию, выполняющую две различных операции

372
Изменение существующей строки

Изменение существующей строки

ЗдравствуйтеМне хотелось бы понять, как можно реализовать изменение строки, введенной прежде с помощью функции getline в консольном приложении

193
Как отследить утечку памяти

Как отследить утечку памяти

Работаю под Visual StudioКак узнать, есть ли в программе утечка памяти или нет?

204
:hover не работает

:hover не работает

Не работает hover

293