2012-09-26 16 views
6

Estoy escribiendo una prueba de unidad para un Validator personalizado en un QTableView usando el QTestLib framework. Uno de los casos de prueba más básicos podría describirse así:¿Cómo se puede editar una celda QTableView desde una prueba de unidad QTest?

Haga doble clic en la celda de la tabla en la tercera y cuarta fila, y agregue el número '5' a su contenido.

No es suficiente con cambiar el valor en el modelo ni nada, el caso de prueba se realice de esta manera:

  1. haga doble clic en la celda de tabla para establecer en el modo de edición
  2. Presione la tecla [Fin].
  3. Presione la tecla [5].

Nota: This question tiene una respuesta sobre cómo configurar una celda de tabla en el modo de edición de código, sin embargo, la prueba de la unidad deberá tratar de atenerse a las posibilidades de un usuario humano, es decir, acciones/ratón teclado.

He descubierto que la posición X/Y de una celda se puede recuperar usando QTableView::columnViewportPosition(int) y QTableView::rowViewportPosition(int). Sin embargo, hacer doble clic en la ubicación especificada utilizando QTest::mouseDClick(...) ni selecciona la celda ni se pone en el modo de edición:

// 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)); 

¿Cómo puedo aplicar el caso de prueba que he descrito anteriormente, utilizando sólo las acciones/ratón teclado?

PS: Estoy tratando esto bajo Windows XP de 32 bits y Qt 4.6.1

Respuesta

5

Hay varias cosas a considerar cuando se trata de editar en un QTableView a través de eventos simulados:

Un QTableView no lo hace muestra sus celdas directamente, lo hace usando su viewport(). Del mismo modo, el evento de doble clic se debe enviar a la ventana gráfica en lugar de a la vista de tabla.

Ahora cuando haces

QTest::mouseDClick(m_pTableView->viewport(), Qt::LeftButton, 
        NULL, QPoint(xPos, yPos)); 

se seleccionará la celda, pero no en el modo de edición (a diferencia de un doble clic iniciada humana que al instante se pone la célula en el modo de edición, incluso si la vista de tabla no tenía enfocarse antes). Sin embargo, si agrega un solo clic en la misma ubicación antes del doble clic, ¡funcionará!

Si luego envió la tecla [Fin] a la ventana gráfica, el cursor no saltará al final del contenido de la celda de la tabla, sino que se seleccionará la última celda de la fila actual.
Para cambiar el contenido de la celda de tabla, debe enviar el evento al widget de editor actual. La forma más sencilla de hacerlo es el uso de QWidget::focusWidget()

QTest::keyClick(m_pTableView->viewport()->focusWidget(), Qt::Key_End); 

Tenga en cuenta que el uso de esa manera puede ser peligroso, aunque como focusWidget() puede devolver NULL.


Con ese conocimiento, el caso de prueba puede ser programado de la siguiente manera:

// 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); 

(Nota: si usted quiere comprobar esto, puede agregar QTest :: qWait (1000) comandos después de cada evento)


Si está utilizando el _data() funciona como se describe here, tenga en cuenta que no se puede recuperar el focusWidget() en el momento de la creación de datos. He resuelto este problema creando una interfaz personalizada ITestAction con solo una función virtual pura "execute()". Luego agregué subclases con un constructor similar a las funciones QTest::mouseClick(...) etc. Estas clases simplemente llaman a las funciones QTest pero usan el widget en sí o su widget de enfoque como parámetro, dependiendo de un indicador booleano adicional. La ranura _data() almacena una lista QList < ITestAction *> para cada fila de datos, y la ranura de prueba real itera sobre esa lista y ejecuta execute() en cada elemento antes de que se realice la validación.

+0

Esta es exactamente la respuesta que necesitaba, muchas gracias :) – astrojuanlu

+0

¿Cuál es el + 5 y + 10 para en - int xPos = m_ptableView-> columnViewportPosition (2) + 5; int yPos = m_pTableView-> rowViewportPosition (3) + 10; – NiladriBose

+1

@NiladriBose: estos son números de píxeles. Como estamos simulando clics, probablemente deseemos hacer clic en algún lugar dentro de la celda, no en su borde, solo para asegurarnos de que se selecciona la celda correcta. –

Cuestiones relacionadas