GTK+ DoubleClick vs SingleClick (Как правильно обработать события)
Модератор: Модераторы разделов
-
- Сообщения: 345
- ОС: Fedora
GTK+ DoubleClick vs SingleClick
При обработке события GdkEventType GDK_2BUTTON_PRESS сначала ренерируется собитие GDK_BUTTON_PRESS
Вопрос, как правильно обработать события двоного нажатия мыши так, чтобы выполнялось условие только для GDK_2BUTTON_PRESS и не выполнялось для GDK_BUTTON_PRESS и наоборот?
Сейчас при двойном клике выполняются - команда для двойного клика и 2 раза комада для одинарного клика
Вопрос, как правильно обработать события двоного нажатия мыши так, чтобы выполнялось условие только для GDK_2BUTTON_PRESS и не выполнялось для GDK_BUTTON_PRESS и наоборот?
Сейчас при двойном клике выполняются - команда для двойного клика и 2 раза комада для одинарного клика
-
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: GTK+ DoubleClick vs SingleClick
1. В структуре
можно использовать параметр time (у GDK_BUTTON_PRESS и GDK_2BUTTON_PRESS он в этом случае будет одинаковым). Т.е. в GDK_BUTTON_PRESS прочитать следующее сообщение (не забирая из очереди) и если это двойной клик - то ничего не делать. Время может и не надо проверять даже.
2. Если вам нужен клик (нажатие-отпускание), то можно реакцию поместить в отпускание, а т.к. порядок:
то GDK_BUTTON_RELEASE после GDK_2BUTTON_PRESS можно игнорировать (флаг использовать к примеру).
PS может в GDK есть для этого специальный прием - не в курсе
Код: Выделить всё
typedef struct {
GdkEventType type;
GdkWindow *window;
gint8 send_event;
guint32 time;
gdouble x;
gdouble y;
gdouble *axes;
guint state;
guint button;
GdkDevice *device;
gdouble x_root, y_root;
} GdkEventButton;
можно использовать параметр time (у GDK_BUTTON_PRESS и GDK_2BUTTON_PRESS он в этом случае будет одинаковым). Т.е. в GDK_BUTTON_PRESS прочитать следующее сообщение (не забирая из очереди) и если это двойной клик - то ничего не делать. Время может и не надо проверять даже.
2. Если вам нужен клик (нажатие-отпускание), то можно реакцию поместить в отпускание, а т.к. порядок:
- GDK_BUTTON_PRESS
- GDK_BUTTON_RELEASE
- GDK_BUTTON_PRESS
- GDK_2BUTTON_PRESS
- GDK_BUTTON_RELEASE
- GDK_BUTTON_PRESS
- GDK_3BUTTON_PRESS
- GDK_BUTTON_RELEASE
то GDK_BUTTON_RELEASE после GDK_2BUTTON_PRESS можно игнорировать (флаг использовать к примеру).
PS может в GDK есть для этого специальный прием - не в курсе
-
- Сообщения: 1338
- Статус: We are all Kosh
- ОС: Fedora 10
Re: GTK+ DoubleClick vs SingleClick
Код: Выделить всё
if (type == GDK_2BUTTON_PRESS) {
on_double_clicked_action();
}
не?
LightLang Team
-
- Сообщения: 345
- ОС: Fedora
Re: GTK+ DoubleClick vs SingleClick
Не понятен ни первый вариант, ни второй
как время события отражается на GDK_BUTTON_PRESS и GDK_2BUTTON_PRESS?
Все равно же будет
и сотвествено обработка двойного клика, как - один клик, один клик, двойной клик
Не понятно ничего. Можно по подробнее
не, вопрос не в этом
Повторюсь, нужно чтоб по двойному клику выполнялось действие BBB, по одинарному клику действие AAA.
Сейчас же имею:
один клик - действие AAA (все нормально)
двойной клик - действие AAA, действие AAA, действие BBB (а нужно только действие BBB)
NickLion писал(а): ↑26.03.2009 16:111. можно использовать параметр time (у GDK_BUTTON_PRESS и GDK_2BUTTON_PRESS он в этом случае будет одинаковым). Т.е. в GDK_BUTTON_PRESS прочитать следующее сообщение (не забирая из очереди) и если это двойной клик - то ничего не делать. Время может и не надо проверять даже.
как время события отражается на GDK_BUTTON_PRESS и GDK_2BUTTON_PRESS?
Все равно же будет
- GDK_BUTTON_PRESS
- GDK_BUTTON_PRESS
- GDK_2BUTTON_PRESS
и сотвествено обработка двойного клика, как - один клик, один клик, двойной клик
NickLion писал(а): ↑26.03.2009 16:112. Если вам нужен клик (нажатие-отпускание), то можно реакцию поместить в отпускание, а т.к. порядок:
- GDK_BUTTON_PRESS
- GDK_BUTTON_RELEASE
- GDK_BUTTON_PRESS
- GDK_2BUTTON_PRESS
- GDK_BUTTON_RELEASE
- GDK_BUTTON_PRESS
- GDK_3BUTTON_PRESS
- GDK_BUTTON_RELEASE
то GDK_BUTTON_RELEASE после GDK_2BUTTON_PRESS можно игнорировать (флаг использовать к примеру).
Не понятно ничего. Можно по подробнее
(BlackStar) писал(а):не?
не, вопрос не в этом
Повторюсь, нужно чтоб по двойному клику выполнялось действие BBB, по одинарному клику действие AAA.
Сейчас же имею:
один клик - действие AAA (все нормально)
двойной клик - действие AAA, действие AAA, действие BBB (а нужно только действие BBB)
-
- Сообщения: 1338
- Статус: We are all Kosh
- ОС: Fedora 10
Re: GTK+ DoubleClick vs SingleClick
Еще раз:
Код: Выделить всё
on_ clicked(... GdkEventButton * event ...) {
if (event->type == GDK_2BUTTON_PRESS) {
BBB
} else {
AAA
}
}
LightLang Team
-
- Сообщения: 345
- ОС: Fedora
Re: GTK+ DoubleClick vs SingleClick
BlackStar писал(а): ↑26.03.2009 18:43Еще раз:
Код: Выделить всё
on_ clicked(... GdkEventButton * event ...) { if (event->type == GDK_2BUTTON_PRESS) { BBB } else { AAA } }
Этот код архилогичен, но при двойном клике будет выполнено:
ААА, ААА, ВВВ.
Потому как:
1/ GDK_BUTTON_PRESS
условие - ложь, будет выпонено else {}, т.е. ААА
2/ GDK_BUTTON_RELEASE
3/ GDK_BUTTON_PRESS
условие - ложь, будет выпонено else {}, т.е. ААА
4/ GDK_2BUTTON_PRESS
условие - истина, будет выпонено BBB
Собственно именно в этом и вопрос:
Как при двойном клике выполнить только ВВВ?
-
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: GTK+ DoubleClick vs SingleClick
1. При получении GDK_BUTTON_PRESS смотрите какое следующее событие - если это GDK_2BUTTON_PRESS (вот здесь для особо замороченных людей вроде меня я и предлагал проверить соответствие времени), то игнорируете GDK_BUTTON_PRESS.
2. Вообще игнорируете GDK_BUTTON_PRESS, а обработка при получении GDK_BUTTON_RELEASE, но полезные действия только если флаг=0, а в конце в любом случае флаг сбрасываете в 0. При получении GDK_2BUTTON_PRESS делаете нужное Вам, и устанавливаете флаг=1.
2. Вообще игнорируете GDK_BUTTON_PRESS, а обработка при получении GDK_BUTTON_RELEASE, но полезные действия только если флаг=0, а в конце в любом случае флаг сбрасываете в 0. При получении GDK_2BUTTON_PRESS делаете нужное Вам, и устанавливаете флаг=1.
-
- Сообщения: 807
- ОС: ubuntu
Re: GTK+ DoubleClick vs SingleClick
Что то мне кажется что это неразрешимая задача.
Сигнал нажатия на кнопку первичен для определения двойного клика поэтому его игнорировать не получиться.
Функция при нажатии будет выполняться в любом случае, поэтому можно написать хитрый обработчик который будет перед выполнением функции проверять не являлось ли нажатие составным сигналом двойного клика а для этого нужно выдержать определённую паузу, но это только лишняя трата времени по моему.
цепочка сигналов при двойном клике
1. GDK_BUTTON_PRESS
2. GDK_BUTTON_RELEASE
3. GDK_BUTTON_PRESS
4. GDK_2BUTTON_PRESS
5. GDK_BUTTON_RELEASE
можно сделать примерно так
нажатие
val = TRUE
функция с паузой (должна превышать паузу между кликами)
если TRUE выполнение
двойной клик
val = FALSE
таким образом во время двойного клика функции отправляются в режим ожидания и если двойной клик обнуляет переменную значит они не выполняются.
Сигнал нажатия на кнопку первичен для определения двойного клика поэтому его игнорировать не получиться.
Функция при нажатии будет выполняться в любом случае, поэтому можно написать хитрый обработчик который будет перед выполнением функции проверять не являлось ли нажатие составным сигналом двойного клика а для этого нужно выдержать определённую паузу, но это только лишняя трата времени по моему.
цепочка сигналов при двойном клике
1. GDK_BUTTON_PRESS
2. GDK_BUTTON_RELEASE
3. GDK_BUTTON_PRESS
4. GDK_2BUTTON_PRESS
5. GDK_BUTTON_RELEASE
можно сделать примерно так
нажатие
val = TRUE
функция с паузой (должна превышать паузу между кликами)
если TRUE выполнение
двойной клик
val = FALSE
таким образом во время двойного клика функции отправляются в режим ожидания и если двойной клик обнуляет переменную значит они не выполняются.
-
- Сообщения: 345
- ОС: Fedora
Re: GTK+ DoubleClick vs SingleClick
Каким средствами это делается? проверить соответствие времени чему? Как смотреть следующее событие?
Но ведь GDK_BUTTON_RELEASE следует и за GDK_BUTTON_PRESS и за GDK_2BUTTON_PRESS
Если можно, то хотя бы псевдокод напишите пожалуйста, пока не понимаю логики выше сказанного

-
- Сообщения: 345
- ОС: Fedora
Re: GTK+ DoubleClick vs SingleClick
Правильно ли я понимаю:
Код: Выделить всё
on_clicked (... GdkEventButton...) {
val = TRUE;
delay (чуть больше 1/4 секунды);
if (event->type == GDK_2BUTTON_PRESS)
{
val = FALSE;
BBB();
}
else
{
if (val == TRUE)
AAA();
}
}
-
- Сообщения: 807
- ОС: ubuntu
Re: GTK+ DoubleClick vs SingleClick
alkesta писал(а): ↑27.03.2009 14:39Правильно ли я понимаю:
Код: Выделить всё
on_clicked (... GdkEventButton...) { val = TRUE; delay (чуть больше 1/4 секунды); if (event->type == GDK_2BUTTON_PRESS) { val = FALSE; BBB(); } else { if (val == TRUE) AAA(); } }
Нет немного не так.
Функция ААА запускается в любом случае, но в теле функции стоит пауза и затем проверка переменной, если переменная после паузы TRUE значит двойного клика небыло и соответственно можно выполнять содержимое функции ААА.
Код: Выделить всё
on_clicked (... GdkEventButton...) {
if (event->type == GDK_2BUTTON_PRESS)
{
val = FALSE;
BBB();
}
else
{
val = TRUE;
AAA()
{
delay(1/4);
if(val == TRUE)
{
основной код функции;
}
};
}
}
-
- Сообщения: 345
- ОС: Fedora
Re: GTK+ DoubleClick vs SingleClick
Не понятно, возможно Вы хотели сказать это:
Код: Выделить всё
on_clicked (... GdkEventButton...) {
if (event->type == GDK_2BUTTON_PRESS)
{
val = FALSE;
BBB();
}
else
{
val = TRUE;
AAA();
}
}
AAA(void){
delay(1/4);
if(val == TRUE) /*val глобальная или значение получается по ссылке на val*/
{
основной код функции;
}
}
-
- Сообщения: 807
- ОС: ubuntu
Re: GTK+ DoubleClick vs SingleClick
alkesta писал(а): ↑27.03.2009 15:58Не понятно, возможно Вы хотели сказать это:
Код: Выделить всё
on_clicked (... GdkEventButton...) { if (event->type == GDK_2BUTTON_PRESS) { val = FALSE; BBB(); } else { val = TRUE; AAA(); } } AAA(void){ delay(1/4); if(val == TRUE) /*val глобальная или значение получается по ссылке на val*/ { основной код функции; } }
Ну да, просто я функцию выносить не стал, это же всё равно псевдокод

-
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: GTK+ DoubleClick vs SingleClick
1 вариант. Имелось в виду:
2. Имелось в виду:
Код: Выделить всё
if( event->type == GDK_BUTTON_PRESS ) {
event2 = следующее сообщение из очереди; // но оставить его в очереди
if( event2->type == GDK_2BUTTON_PRESS /* && event2->time == event->time */ )
{
забрать сообщение из очереди;
выполнить действие для двойного клика;
} else {
выполнить действие обычного клика;
}
}
2. Имелось в виду:
Код: Выделить всё
обработка GDK_BUTTON_PRESS { flag = 0; }
обработка GDK_2BUTTON_PRESS {
flag = 1;
обработка двойного клика;
}
обработка GDK_BUTTON_RELEASE {
if( !flag ) {
обработка одинарного клика;
}
flag = 0;
}
-
- Сообщения: 345
- ОС: Fedora
Re: GTK+ DoubleClick vs SingleClick
NickLion писал(а): ↑27.03.2009 19:252. Имелось в виду:
Код: Выделить всё
обработка GDK_BUTTON_PRESS { flag = 0; } обработка GDK_2BUTTON_PRESS { flag = 1; обработка двойного клика; } обработка GDK_BUTTON_RELEASE { if( !flag ) { обработка одинарного клика; } flag = 0; }
При двойном клике получается:
1. GDK_BUTTON_PRESS установка flag = 0
2. GDK_BUTTON_RELEASE flag == 0 условие верно | {исполняется код обработки одинарного клика} | установка flag = 0
3. GDK_BUTTON_PRESS установка flag = 0
4. GDK_2BUTTON_PRESS {исполняется код обработки двойного клика} | установка flag = 1
5. GDK_BUTTON_RELEASE flag == 1 условие не верно | устанановка flag = 0
т.е. при двойном клике {исполняется код обработки одинарного клика} и {исполняется код обработки двойного клика}. Или я что-то не так понимаю?
-
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: GTK+ DoubleClick vs SingleClick
Перечитал тему, я Вас тогда не понял. Я думал, что проблема в повторной обработке одинарного нажатия. Если нужно, чтобы при двойном клике не был обработан даже первый клик, то единственный выход - задержка по времени перед обработкой нажатия (как говорил sergeyvp), т.к. в момент первого нажатия система не может знать - будет второй клик или нет. Хотя имхо - надо передумать интерфейс. Это нелогичное поведение. Плюс к тому же - мы обычно пользуемся не системами реального времени, поэтому что произойдет раньше, а что позже - вопрос не всегда явный. Как бы не замучаться с этими таймерами/задержками.
Задержка должна быть не менее 1/4 секунды (хм... это не настраиваемый параметр? странно...):
Задержка должна быть не менее 1/4 секунды (хм... это не настраиваемый параметр? странно...):
For a double click to occur, the second button press must occur within 1/4 of a second of the first. For a triple click to occur, the third button press must also occur within 1/2 second of the first button press.