Как вы можете редактировать ячейку QTableView из модульного теста QTest?
Я пишу модульный тест для пользовательского Validator в QTableView с использованием инфраструктуры QTestLib. Один из самых простых тестовых случаев можно описать так:
Дважды щелкните ячейку таблицы в третьем столбце и четвертой строке и добавьте число 5 к ее содержимому.
Недостаточно просто изменить значение в модели или что-либо еще, контрольный пример должен выполнить это так:
- Дважды щелкните ячейку таблицы, чтобы перевести ее в режим редактирования.
- Нажмите клавишу [Конец].
- Нажмите клавишу [5].
Примечание: на этот вопрос есть ответ о том, как перевести ячейку таблицы в режим редактирования из кода, однако модульный тест должен попытаться придерживаться возможностей человека, то есть действий мыши / клавиатуры.
Я обнаружил, что положение X/Y ячейки можно получить с помощью QTableView::columnViewportPosition( int) и QTableView:: rowViewportPosition (int). Однако двойной щелчок в указанном месте с помощью QTest::mouseDClick(...) не выделяет ячейку и не переводит ее в режим редактирования:
// Retrieve X/Y coordinates of the cell in the third column and the fourth row
int xPos = m_pTableView->columnViewportPosition( 2 );
int yPos = m_pTableView->rowViewportPosition( 3 );
// This does not work
QTest::mouseDClick( m_pTableView, Qt::LeftButton, QPoint( xPos, yPos ) );
Как я могу реализовать контрольный пример, который я описал выше, используя только действия мыши / клавиатуры?
PS: я пытаюсь это под Windows XP 32 бит и Qt 4.6.1
1 ответ
Есть несколько вещей, которые следует учитывать при попытке редактирования в QTableView с помощью смоделированных событий:
QTableView не отображает свои ячейки напрямую, он делает это с помощью своего viewport (). Аналогично, событие двойного щелчка должно быть отправлено в область просмотра вместо самого табличного представления.
Теперь, когда вы делаете
QTest::mouseDClick( m_pTableView->viewport(), Qt::LeftButton,
NULL, QPoint( xPos, yPos ) );
ячейка будет выделена, но не в режиме редактирования (в отличие от двойного щелчка, инициированного человеком, который мгновенно переводит ячейку в режим редактирования, даже если представление таблицы ранее не имело фокусировки). Если вы добавите один щелчок в том же месте перед двойным щелчком, это сработает!
Если вы затем отправите нажатие клавиши [End] в область просмотра, курсор не перейдет к концу содержимого ячейки таблицы, а вместо этого будет выбрана последняя ячейка в текущей строке.
Чтобы изменить содержимое ячейки таблицы, вы должны вместо этого отправить событие в текущий виджет редактора. Самый простой способ сделать это - использовать QWidget::focusWidget()
QTest::keyClick( m_pTableView->viewport()->focusWidget(), Qt::Key_End );
Обратите внимание, что такое использование может быть небезопасным, так как focusWidget () может возвращать NULL.
Обладая этими знаниями, контрольный пример может быть запрограммирован следующим образом:
// Note: The table view must be visible at this point
// Retrieve X/Y coordinates of the cell in the third column and the fourth row
int xPos = m_pTableView->columnViewportPosition( 2 ) + 5;
int yPos = m_pTableView->rowViewportPosition( 3 ) + 10;
// Retrieve the viewport of the table view
QWidget* pViewport = m_pTableView->viewport();
// Double click the table cell to set it into editor mode
// Note: A simple double click did not work, Click->Double Click works, however
QTest::mouseClick ( pViewport, Qt::LeftButton, NULL, QPoint( xPos, yPos ) );
QTest::mouseDClick( pViewport, Qt::LeftButton, NULL, QPoint( xPos, yPos ) );
// Simulate [End] keypress
QTest::keyClick( pViewport->focusWidget(), Qt::Key_End );
// Simulate [5] keypress
QTest::keyClick( pViewport->focusWidget(), Qt::Key_5 );
(Примечание: если вы хотите это проверить, вы можете добавить команды QTest::qWait( 1000) после каждого события)
Если вы используете функции _data(), как описано здесь, обратите внимание, что вы не можете получить focusWidget () во время создания данных. Я решил эту проблему, создав пользовательский интерфейс ITestAction
только с чисто виртуальной функцией execute(). Затем я добавил подклассы с похожим конструктором QTest::mouseClick(...) etc
функции. Эти классы просто вызывают функции QTest, но используют либо сам виджет, либо его виджет фокуса в качестве параметра, в зависимости от дополнительного логического флага. Слот _data() затем сохраняет QList