Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: Гурман от Апрель 01, 2015, 15:11



Название: Вот тебе, бабушка, и doubleClick...
Отправлено: Гурман от Апрель 01, 2015, 15:11
Потребовалось в QTableWidget обработать отдельно одинарный клик на ячейку, отдельно двойной. Всё нарисовано в Дизайнере, там же и созданы слоты для сигналов таблицы.

Код:
void ManagerDialog::on_tableWidget_cellClicked(int row, int column)
{
    qDebug() << "single";
}

void ManagerDialog::on_tableWidget_cellDoubleClicked(int row, int column)
{
    qDebug() << "double";
}

qDebug вставил, когда увидел, что при двойном клике на ячейку получаю совсем не то, что ожидал. А выдаёт при двойном клике на строку таблицы вот что:

Цитировать
single
double
single
:o

Скорость нажатия ни при чем - и дабл срабатывает, и у меня средняя кнопка мыши всегда двойной клик выдает, нигде проблем не было последние годы. Поискал в Инете - несколько человек с таким столкнулись, но нормального решения не видно.

Может я пропустил чего? Сорри, если боян - никогда до сих пор не требовалось двойного клика на таблицу с нередактируемыми ячейками.


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Пантер от Апрель 01, 2015, 15:18
На сколько я помню, придется самому реализовать игнорирование одинарного клика в течении n времени (можно у QApplication получить, вроде).


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Bepec от Апрель 01, 2015, 15:33
Это как бы логично на мой взгляд и всегда так работало.
PS не вижу способа кроме костыля, который будет игнорить нажатия :D


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: PimenS от Апрель 01, 2015, 15:38
А если попробовать через void QWidget::mouseDoubleClickEvent(QMouseEvent * event)?


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Гурман от Апрель 01, 2015, 15:39
На сколько я помню, придется самому реализовать игнорирование одинарного клика в течении n времени (можно у QApplication получить, вроде).

Прям аж скрипом несмазанных Окон повеяло...  >:(


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Bepec от Апрель 01, 2015, 15:40
Угу, прям скрип прямо несмазанных.
И никогда не появится тема - "Как хорошо что Qt обрабатывает double click как 2 click, это ведь так хорошо в моём проекте".

PS ругаете правильную вещь, а зря :)


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Гурман от Апрель 01, 2015, 15:41
А если попробовать через void QWidget::mouseDoubleClickEvent(QMouseEvent * event)?

выяснять, в какую ячейку таблицы кликнули, сложнее, чем интервал времени "отождать"


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Гурман от Апрель 01, 2015, 15:43
Угу, прям скрип прямо несмазанных.
И никогда не появится тема - "Как хорошо что Qt обрабатывает double click как 2 click, это ведь так хорошо в моём проекте".

PS ругаете правильную вещь, а зря :)

Неужели кому-то когда-то где-то потребовалось прямо в таблице выделять из даблклика первый клик или последний?? Даблклик - это должно быть на системном уровне одно действие, а не два. И тем более, не три.

Причем, это только на ячейках таблицы. Например, на айтемах графической сцены всё нормально работает - даблклик это дабл, а сингл это сингл.


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Bepec от Апрель 01, 2015, 15:52
Не соглашусь) каждое действие пользователя должно быть отображено "на уровне системы". А дабл клик это именно два клика. Не полтора, не один и четвертинка, а именно два клика :)


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Гурман от Апрель 01, 2015, 15:57
Два клика - это НЕ ТРИ СИГНАЛА!

И для исключения подобных ситуаций надо иметь настройку типа QTableWidget::setProcessDoubleClickSeparately(bool) - причем именно у виджета таблицы, поскольку в остальных местах нормально работает

хотя бы потому, что в 99.99% случаев в реальной жизни надо обрабатывать двойной клик и одинарный как единые цельные команды, и только в 0.01% случаев надо выделять из двойного клика первый и второй


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Igors от Апрель 01, 2015, 16:04
Цитировать
single
double
single
:o
Много лет я (как и другие) отслеживал сам двойной клик, такого события просто не было в ОС. Тут дают - еще и недоволен. Нужно отбросить третий - ну так фильтрок, засейвил последнее время double и сравнил, всех делов 5 мин. Ну зажрались и обленились  :'(


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: PimenS от Апрель 01, 2015, 16:07
выяснять, в какую ячейку таблицы кликнули, сложнее, чем интервал времени "отождать"

Можно подробнее. Не пойму в чем сложность получения currentIndex() или currentItem()?


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Гурман от Апрель 01, 2015, 16:10
Много лет назад я на Ассемблере сам прерывания обрабатывал, и вызывает неподдельное удивление, что в ТАКОМ высокоуровневом фреймворке, как Qt далеко не первой версии, приходится сползать чуть ли не на тот же уровень.

Скорее всего, просто авторы забыли, как и во многих других местах. Придётся suggestion писать, чтобы сделали отключение этой ненужной фичи.


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Bepec от Апрель 01, 2015, 16:13
Последняя реплика явно не в тему, хотя пишите пишите - думаю вам ответят, что вы неправы :)

Дабл клик это 3 (ТРИ) события. Это 2 нажатия мышки и после их обработки событие двойного клика.

Тут попутан просто порядок, хотя тоже можно поспорить :)


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: sociopath от Апрель 01, 2015, 16:19
Всегда ловил при даблклике сначала сигнал на singleClick, потом сигнал на doubleClick (итого 2), на Qt 4.5, 4.6 и 4.8 под WIN и X11. А вообще мне что-то очень сомнительно, что количество этих сигналов как-либо регламентировано (не говоря уж про их порядок).


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Гурман от Апрель 01, 2015, 16:22
Можно подробнее. Не пойму в чем сложность получения currentIndex() или currentItem()?

В разнице между сложно и сложнее.

На таймере делается в полприхлопа:

Код:

bool wasdclick = false;
QTimer clicktimer;

void ManagerDialog::on_tableWidget_cellClicked(int row, int column)
{
    if( !wasdclick ) //
        clicktimer.singleShot( QApplication::doubleClickInterval(), this, SLOT(sendClick()) );
}

void ManagerDialog::on_tableWidget_cellDoubleClicked(int row, int column)
{
    wasdclick = true;
    qDebug() << "double";
}

void ManagerDialog::sendClick()
{
    if( ! wasdclick )
        qDebug() << "single";
    wasdclick = false;
}


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: sociopath от Апрель 01, 2015, 16:26
Прошу прощения за неточность, при AllEditTriggers второй сигнал clicked "съедается". При NoEditTriggers действительно идет single, double, single


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: sociopath от Апрель 01, 2015, 16:34
Кроме таймера ничего и не получится придумать.
У Qt-шников у самих в коде всякие прекрасные строчки типа:
Код:
    // we may get a double click event later
    if (trigger == SelectedClicked)
        d->delayedEditing.start(QApplication::doubleClickInterval(), this);
(это в QAbstractItemView::edit, например)


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Igors от Апрель 01, 2015, 16:57
Много лет назад я на Ассемблере сам прерывания обрабатывал,
Та кто их тогда не обрабатывал? Разве что бабы - и то находились любительницы. Не надо молодым пыль в глаза пускать  :)

...и вызывает неподдельное удивление, что в ТАКОМ высокоуровневом фреймворке, как Qt далеко не первой версии, приходится сползать чуть ли не на тот же уровень.

Скорее всего, просто авторы забыли, как и во многих других местах. Придётся suggestion писать, чтобы сделали отключение этой ненужной фичи.
Ну сказали тоже. А если мне пофиг тот double-click. я хочу использовать свой интервал времени и/или допуск смещения мышака?

На таймере делается в полприхлопа:
И что, каждый раз ждем-с не будет ли еще нажатия? Только если мерзавец-юзер не нажал - тогда уж работаем? Как-то смахивает на "два притопа"  :)


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Гурман от Апрель 01, 2015, 17:07
А если мне пофиг тот double-click. я хочу использовать свой интервал времени и/или допуск смещения мышака?

так может работать и по-умолчанию, для совместимости со старым кодом

а если надо по-нормальному, то вызов QTableWidget::setProcessDoubleClickSeparately( true ) и пусть работает по-нормальному

что, каждый раз ждем-с не будет ли еще нажатия? Только если мерзавец-юзер не нажал - тогда уж работаем?

а это вот совершенно не важно, важно то, что работает как требуется


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Igors от Апрель 10, 2015, 05:36
А история-то имеет продолжение. Вчера полезло у меня какое-то багво на double-click, начал разбираться. Никаких 3 событий в Qt 5 нет (OSX + Qt 5.4, Win7 + Qt 5.3.2). Вот печать (первое событие QWindow, второе QWidget, это нормально)

Цитировать
5 MouseButtonPress QWidgetWindow(0x266e7f0, name = "QWidgetClassWindow") delta = 4992
6 MouseButtonPress QWidget(0x266e4d0) delta = 0

7 MouseButtonRelease QWidgetWindow(0x266e7f0, name = "QWidgetClassWindow") delta = 120
8 MouseButtonRelease QWidget(0x266e4d0) delta = 0

9 MouseButtonPress QWidgetWindow(0x266e7f0, name = "QWidgetClassWindow") delta = 88
10 MouseButtonDblClick QWidgetWindow(0x266e7f0, name = "QWidgetClassWindow") delta = 0
11 MouseButtonDblClick QWidget(0x266e4d0) delta = 0

12 MouseButtonRelease QWidgetWindow(0x266e7f0, name = "QWidgetClassWindow") delta = 120
13 MouseButtonRelease QWidget(0x266e4d0) delta = 0
Тестовый пример прилагаю.

Однако же.... как все (включая меня) доверчивы и как легко нас ввести в заблуждение  :)


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Bepec от Апрель 10, 2015, 08:46
Igors - а где нет 3 событий?

Я вижу тут 2 release и 1 double click.
2 + 1 = ????


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Igors от Апрель 10, 2015, 09:48
Igors - а где нет 3 событий?

Я вижу тут 2 release и 1 double click.
2 + 1 = ????
В пятерке сначала окно (QWindow) принимает событие а потом диспатчит его виджету. Где delta = 0 значит то же самое событие. Итого при dbl виджет получает

MouseButtonPress
MouseButtonRelease
MouseButtonDblClick
MouseButtonRelease


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Гурман от Апрель 10, 2015, 10:18
в 1-м сообщении я говорил не о 3х событиях, а о 3х сигналах


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Bepec от Апрель 10, 2015, 10:23
update to Гурман:
Принципиальной разницы нет, 3 события вызывают 3 сигнала.

To Igors:
Начну с теории.
Вы надеюсь в курсе, что приложения делятся на
1. работающие по press кнопок.
2. работающие по release кнопок.

Имеются и смешанные реакции, но это довольно редко.

В данном случае мы видим второй вариант, потому press событие мы отбрасываем. Остаётся
MouseButtonRelease
MouseButtonDblClick
MouseButtonRelease

В данном случае посыл события происходит после второго release, но до отправки события диспетчеру. Т.е. расшифровываем более подробно:

User отпустил кнопку
Обработчик событий, посыл события MouseButtonRelease
User отпустил кнопку
Обработчик событий, посыл события MouseButtonDblClick
Обработчик событий, посыл события MouseButtonRelease

Т.к. очередность посыла событий нигде не описана и не регламентирована, то и возразить нечем.

PS не надо взывать к логике и вашему видению ситуации - нигде не регламентировано, так что всё прочее лишь ваше личное мнение :D


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Igors от Апрель 10, 2015, 11:07
To Igors:
Начну с теории.
Вы надеюсь в курсе, что приложения делятся на
1. работающие по press кнопок.
2. работающие по release кнопок.
Совершенно не в курсе, первый раз слышу чтобы хоть что-то кроме драга срабатывало по  release кнопки  :)

В данном случае посыл события происходит после второго release, но до отправки события диспетчеру. Т.е. расшифровываем более подробно:

User отпустил кнопку
Обработчик событий, посыл события MouseButtonRelease
User отпустил кнопку
Обработчик событий, посыл события MouseButtonDblClick
Обработчик событий, посыл события MouseButtonRelease
То есть никакого dbl-click не случится пока мыша зажата? Но вот я прямо в этом письме dbl-click'нул на слово и не отпускаю - а слово почему-то уже подсветилось. Как же так  ???

PS не надо взывать к логике и вашему видению ситуации - нигде не регламентировано, так что всё прочее лишь ваше личное мнение :D
Типа "зашланговался" чтобы иметь отмазки когда возьмут за жопу :) Образы Николая Васильевича бессмертны, такие люди будут всегда  :)


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Bepec от Апрель 10, 2015, 11:12
Как то невнятно вы описали в чем я неправ :) Как определитесь и сформулируете, пожалуйста :)


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Гурман от Апрель 10, 2015, 11:41
update to Гурман:
Принципиальной разницы нет, 3 события вызывают 3 сигнала.

Уго, но моё замечание не к вам относилось. Суть вы сами пояснили. Добавлю только - сигналы о кнопках посылаются при отпускании кнопок. Но сигнал о даблклике посылается при втором нажатии - если оно было обнаружено в пределах установленного интервала времени. Справедливости ради, есть сигнал QTableWidget::itemPressed( QTableWidgetItem * item ) - первое нажатие, я его даже сразу не заметил.

На самом деле, в сигналах сбивают с толку их названия itemClicked и itemDoubleClicked, хотя itemPressed - часть этой последовательности, но по названию этого не видно. И в документации не сказано, в какой последовательности они идут. Было бы это описано - нет вопросов.


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Bepec от Апрель 10, 2015, 12:04
Как любят говорить разработчики open sourse продуктов - это тема для самостоятельного изучения :D


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Гурман от Апрель 10, 2015, 12:31
ну или, хотя бы, назвали бы itemDoublePressed - уже совсем другое дело


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Igors от Апрель 10, 2015, 12:32
в 1-м сообщении я говорил не о 3х событиях, а о 3х сигналах
То же самое, в 5.4 ничего такого нет, приходит сигнал cellClicked, затем cellDoubleClicked - и все. И отпускания мыши никто не ждет


Название: Re: Вот тебе, бабушка, и doubleClick...
Отправлено: Igors от Апрель 24, 2015, 09:41
И еще нюансик - если виджет не обрабатывает doubleClick, то он получит 2 mousePressEvent.