Russian Qt Forum

Qt => Общие вопросы => Тема начата: biz_0n от Апрель 20, 2010, 00:51



Название: Потоки
Отправлено: biz_0n от Апрель 20, 2010, 00:51
возникла необходимость приостанавливать главный поток.
Нужно реализовать клавиатуру, программа запрашивает пин-код, а пользователь должен его ввести и нажать кнопку подтверждения. Запрос производится с помощью метода
     int readPin();
которая возвращает сам пин-код.

моя идея была такая: нажатия обрабатываются в отдельном потоке, до тех пор, пока не будет нажата клавиша подтверждения, пока идёт обработка нажатий, все остальные ф-ции ждут завершения потока, после того, как поток завершился, ф-ция readPin возвращает пин-код
Код:
int KBDListener::readPin()
{
pin = 0;
i = 0;
mutex.lock();
start();
waitPin.wait(&mutex);
qDebug() << pin;
quit();
return pin;
}
void KBDListener::run()
{
connect(imp, SIGNAL(keyPressed(QObject*)), this, SLOT(keyHandler(QObject*)));
while(i < 4)
{

}
if ( i == 4){
mutex.unlock();
return;
}
}
void KBDListener::keyHandler(QObject* obj)
{
pin = pin * 10 + ((QPushButton*)obj)->text().toInt();
        ++i;
}

тут показано схематически, вместо обработки кнопки подтверждения, нужно ввести 4 символа
как только выполнение доходит до ожидания мьютекса, всё виснит.
кто что может предложить?


Название: Re: Потоки
Отправлено: Igors от Апрель 20, 2010, 10:13
1) Мне кажется намного проще решить задачу через eventFilter

2) Если нитка захватила мутекс, то она же (и только она) должна его освободить. А сниматься с wait(&mutex) при помощи wakeOne/wakeAll

3) Не видно как KBDListener получит keyPressed


Название: Re: Потоки
Отправлено: alexman от Апрель 20, 2010, 10:26
2) Если нитка захватила мутекс, то она же (и только она) должна его освободить. А сниматься с wait(&mutex) при помощи wakeOne/wakeAll
Есть косяк: если wakeOne/wakeAll вызывается раньше wait(&mutex), то wait будет висеть бесконечно!


Название: Re: Потоки
Отправлено: Amigo_sa от Апрель 20, 2010, 11:07
возникла необходимость приостанавливать главный поток.
Нужно реализовать клавиатуру, программа запрашивает пин-код, а пользователь должен его ввести и нажать кнопку подтверждения. Запрос производится с помощью метода
     int readPin();
которая возвращает сам пин-код.
кто что может предложить?
Можно вообще не использовать функции работы с потоками, а сделать в методе readPin сигнал, который срабатывает, когда пользователь ввел пин. А в слоте, связанном с этим сигналом дальше писать логику в главном потоке.


Название: Re: Потоки
Отправлено: Igors от Апрель 20, 2010, 12:40
Есть косяк: если wakeOne/wakeAll вызывается раньше wait(&mutex), то wait будет висеть бесконечно!
То да. но здесь это неопасно - run() будет ждать ввода пользователя и только тогда отпустит wakeOne. Хотя.. кто знает, а вдруг успеют нажать (4 раза) пока wait сработает??  ::)

Однако я в упор не вижу откуда возьмется keypressed? У нитки exec нет, ладно, добавить можно. Но все равно keypressed  придет в eventLoop главной нитки, которая остановлена и принять его не сможет


Название: Re: Потоки
Отправлено: alexman от Апрель 20, 2010, 12:47
Есть косяк: если wakeOne/wakeAll вызывается раньше wait(&mutex), то wait будет висеть бесконечно!
То да. но здесь это неопасно - run() будет ждать ввода пользователя и только тогда отпустит wakeOne. Хотя.. кто знает, а вдруг успеют нажать (4 раза) пока wait сработает??  ::)

Однако я в упор не вижу откуда возьмется keypressed? У нитки exec нет, ладно, добавить можно. Но все равно keypressed  придет в eventLoop главной нитки, которая остановлена и принять его не сможет
Это так на всякий случай! Код выше даже не смотрел ;)


Название: Re: Потоки
Отправлено: biz_0n от Апрель 20, 2010, 16:33
keypress это сигнал из другого класса, он вызывается при срабатывании другого сигнала, мне пин нужно отдавать только по запросу, хотя и без потоков тут можно обойтись, но там другие косяки появятся, так возможно ли сделать обработку нажатия кнопок в другом потоке и возвращать результат после всех нажатий?


Название: Re: Потоки
Отправлено: Amigo_sa от Апрель 20, 2010, 17:16
keypress это сигнал из другого класса, он вызывается при срабатывании другого сигнала, мне пин нужно отдавать только по запросу, хотя и без потоков тут можно обойтись, но там другие косяки появятся, так возможно ли сделать обработку нажатия кнопок в другом потоке и возвращать результат после всех нажатий?
Нельзя обращаться к GUI-шным объектам из другой нитки


Название: Re: Потоки
Отправлено: Igors от Апрель 20, 2010, 17:20
keypress это сигнал из другого класса, он вызывается при срабатывании другого сигнала, мне пин нужно отдавать только по запросу, хотя и без потоков тут можно обойтись, но там другие косяки появятся, так возможно ли сделать обработку нажатия кнопок в другом потоке и возвращать результат после всех нажатий?
Обрабатывать будет нечего если главная нитка остановлена и не может принять "событие пин" которое подается ОС'ом. Это потом его можно подавать по сигналам и.т. п. - но сначала его надо получить из eventLoop главной нитки