Уже третий день бъюсь над простейшей задачей.
Есть меня QListView. Нужно сделать слот, который бы срабатывал при каждом переключении курсора на другую строку. Ну, то есть, кликнул человек мышкой на нужную строку - выполнился слот. Нажал человек клавишу вверх/вниз, выбралась другая строка, - нужно вызвать тот же слот.
Задача проста. А правильного решения сделать не могу, и вот почему.
Клик мышки по строке списка можно отловить с помощью сигнала clicked() объекта QListView. Он работает правильно, без нареканий.
Но нам еще нужно отлавливать движение клавишами по списку. А это движение можно отловить только с помощью сигнала select-модели списка, именуемого currentRowChanged(). Прототип этого сигнала:
currentRowChanged (const QModelIndex & current, const QModelIndex & previous)
Получается, что слот-обработчик нужно подключать к двум сигналам - к clicked() и currentRowChanged(). Но тогда при выборе нужной записи мышкой, слот срабатывает два (!) раза - один раз от клика, и второй раз из-за того, что засветка переместилась на другую строку. А мне нужно чтоб слот вызывался один раз! Ведь клик-то был один.
Но и это еще не всё. Сигнал currentRowChanged() для QListView, в котором не выбрана ни одна запись, вырабатывается очень хитрым способом. У этого сигнала два параметра - QModelIndeх выбранной записи и QModelIndeх предыдущей записи. Мы для простоты получаем из этих индексов номера записей методом row(). Закономерность генерируемых сигналов и их параметров следующая:
- Если кликнуть по записи с номером 0 (верхняя запись), то сгенерируется один сигнал с параметрами: (0, -1).
- Если кликнуть по записи с номером, отличным от нуля то сгенерируется два (!) сигнала с параметрами: (0, -1) и (номер_записи, 0).
- Если выбрать нужную запись программно (через selection model), то сгенерируется один сигнал с параметрами: (номер_записи, -1).
Из-за такого дикого поведения, слот-обработчик может быть вызван три (!) раза (один раз сигналом clicked(), два раза сигналом currentRowChanged(), если ткнуть на любую запись кроме первой). А мне нужно, чтоб слот был вызван один раз.
Я решил отказаться от сигнала clicked(), так как currentRowChanged() в моей задаче «перекрывает» его функциональность. Но так как этот currentRowChanged() ведет себя дико - генерируется два раза при выборе не первой строки в списке, - я не могу его толком использовать.
Вопрос: как мне отследить выбор строки в списке QListView так, чтобы слот срабатывал только один раз? Нужно учесть, что выбирать пользователь может как кликом мышкой, так и движением засветки клавишами клавиатуры.