Qt4: бесконечные циклы в QThread

Пытаюсь прикрутить libfprint к своему проекту, но поскольку она написана на С и полностью синхронна, стараюсь создать прослойку между ней и qt4.
Создал тред, в котором крутится бесконечный цикл со сканированием, но вот проблема - программа зависает при запуске этого цикла, хотя цикл вроде как должен работать в треде. Что я сделал не так?

Исходник: http://ubuntuone.com/p/esE/

+1
RA9OAJ - 25 Февраль, 2011 - 08:10
Изображение пользователя RA9OAJ.

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

P.S. Попробовал я тут на досуге переделать Вашу программулину, одлнако при линке ругается на недоступные линки функций библиотеки libfprint. Мучался мучился, вроде в параметрах прописано линковать ее. Хз в чем дело так и не допер. Блин, удар по самолюбию, все равно домучаю)))

0
Robotex - 25 Февраль, 2011 - 17:54

А libfprint установлена? Конкретно девовские пакеты?

0
Tonal - 25 Февраль, 2011 - 10:34
Изображение пользователя Tonal.

А в синхронном варианте твой код работает?
И что пишут по поводу libfprint и потоков - ведь может оказаться, что она работает только в главном потоке (как, например, весь Qt GUI)

+1
RA9OAJ - 25 Февраль, 2011 - 12:06
Изображение пользователя RA9OAJ.

Извиняюсь, может я туплю, но в каком смысле "в синхронном варианте"?
По поводу работы в главном или в отдельном потоке скажу лишь то, что по моему мнению, какая разница libfprint в каком она потоке (хотя может я и ошибаюсь)? С QtGUI в этом плане понятнее - в основном потоке обработчик событий, поэтому и возникают проблемы с реализацией выноса элементов GUI в отдельный поток, да и те решаемые, только муторно это все :)
А вот скомпилить код Ваш не получается. ничего не понимаю... вроде линковщик не видит библиотек, но я же поставил dev-пакеты с библиотеками (и статической и динамической), проверил по всем путям в ld.conf - они там лежат (/usr/lib). Мистика...
Тут ниже код слегка измененный cfingerprintscanner.cpp и cfingerprintscanner.h

Просьба попробовать его скомпилить и проверить (и обязательно отписаться). Самому интересно, заработает или нет.
0
Robotex - 25 Февраль, 2011 - 17:56

Начиная с версии 4.4 run больше не виртуальная функция и переопределять ее не рекомендуют.

0
RA9OAJ - 25 Февраль, 2011 - 18:07
Изображение пользователя RA9OAJ.

Ну хз, у меня QtCreator с Qt v4.7 стоит и там в Ассистенте четко написано virtual void run().
Сколько пользуюсь, проблем не было. Так что можете смело брать на вооружение :)

0
Robotex - 26 Февраль, 2011 - 04:00

In Qt 4.3, run() _was_ pure virtual. From 4.4 onwards, the method gained
a default implementation: calling exec(). With this, also the
recommended way of using QThread changed. While you still _can_ use
QThread by reimplementing run(), many people make mistakes doing so. So,
the now recommended way to use QThread is to use it as-is, and simply
move a QObject to the created thread.

0
RA9OAJ - 26 Февраль, 2011 - 17:25
Изображение пользователя RA9OAJ.

Хм, я ж говорю что в офф документации прямо пример есть реализации (тут)

0
_KoT_ - 26 Февраль, 2011 - 05:21
Изображение пользователя _KoT_.

http://doc.crossplatform.ru/qt/4.7.x/qthread.html#run
Я так понял, что у неё еть реализация по умолчанию:void QThread::run (){
  exec();
}

А для своего потока переопределить:void QThread::run (){
  полезные действия;
  exec();
}

0
RA9OAJ - 26 Февраль, 2011 - 17:22
Изображение пользователя RA9OAJ.

Во-во, точно, про exec(); совсем забыл. Вот что значит копипастить со своих же заранее заготовленных шаблонов... важные мелочи совсем забыл.

0
Robotex - 26 Февраль, 2011 - 03:53

Да, теперь цикл работает в параллельном треде, но есть одно но. После первого сканирования, тред завершается. Как заставить его продолжать работать, а завершаться только перед выходом из программы? И как заставить сканирование стартовать при поступлении сигнала?

0
Robotex - 26 Февраль, 2011 - 03:58

Хотя если добавить сигнал, запускающий тред, а при завершении перезапускать, то может получиться нормально.
Вот только как завершить тред, если пользователь не захотел сканироваться, а закрыл программу. У меня при этом выводится: QThread: Destroyed while thread is still running

0
_KoT_ - 26 Февраль, 2011 - 05:24
Изображение пользователя _KoT_.

http://doc.crossplatform.ru/qt/4.7.x/qthread.html#quit
Вызывай перед закрытием.

0
Robotex - 26 Февраль, 2011 - 18:57

Это-то я понял. Но вот как определить, что происходит закрытие.

0
_KoT_ - 26 Февраль, 2011 - 19:10
Изображение пользователя _KoT_.

http://doc.crossplatform.ru/qt/4.7.x/qobject.html#destroyed

А ещё можно вызвать quit(); в деструкторе главного окна.

0
Robotex - 26 Февраль, 2011 - 19:34

Я послал сигнал о закрытии, и даже поймал его в потоке, но функция fp_enroll_finger_img держит поток и не дает ему завершиться, пока пользователь не сканирует палец. Как ее прервать?

0
_KoT_ - 26 Февраль, 2011 - 19:40
Изображение пользователя _KoT_.

Сделай по другому: вызывай tr->quit(); в деструкторе главного окна(ну или класса в котором создаёшь объект потока). Здесь tr указатель на
объект потока.

0
Robotex - 25 Февраль, 2011 - 17:55

В синхронном работает.

0
RA9OAJ - 25 Февраль, 2011 - 18:08
Изображение пользователя RA9OAJ.

Ну раз заработало, то и ладненько.

0
Robotex - 26 Февраль, 2011 - 03:35

Синхронно и раньше работало, а надо асинхронно.

0
Robotex - 28 Февраль, 2011 - 02:25

Оказалось, существует недокументированное асинхронное АПИ. Сижу разбираюсь, если получится - напишу краткое руководство.

0
Robotex - 28 Февраль, 2011 - 08:20

Вроде разобрался с асинхронным АПИ, вот результат (с бинарниками, должен быть установлен libfprint в системе, запускайте в консоли - может не быть прав к некоторым файлам, он покажет к каким): http://ubuntuone.com/p/esE/

Просьба взглянуть - не допустил ли я каких-нибудь архитектурных ошибок? Это еще нужно хорошенько отшлифовать.

З.Ы. Кто нибудь знает, как сбросить состояние устройства после сканирования?

Отправить комментарий

CAPTCHA на основе изображений
Введите цифры