2012-09-26 14 views
6

Ich schreibe einen Komponententest für einen benutzerdefinierten Validator in einem QTableView mit dem QTestLib framework. Einer der grundlegendsten Testfälle könnte wie folgt beschrieben werden:Wie können Sie eine QTableView-Zelle aus einem QTest-Komponententest bearbeiten?

Doppelklicken Sie auf die Tabellenzelle in der dritten Spalte und der vierten Zeile, und fügen Sie die Nummer "5" an seinen Inhalt an.

Es genügt nicht, den Wert im Modell oder etwas zu einfach zu ändern, wird der Testfall es wie folgt durchführen:

  1. Doppel die Tabellenzelle Klicken Sie es in den Bearbeitungsmodus
  2. einstellen
  3. Drücken Sie die Taste [Ende].
  4. Drücken Sie die Taste [5].

Hinweis: This question hat eine Antwort auf, wie eine Tabellenzelle in den Bearbeitungsmodus von Code setzen, aber das Gerät Prüfung muss versuchen, die Möglichkeiten eines menschlichen Benutzers zu halten, das heißt Maus/Tastatur Aktionen.

Ich habe herausgefunden, dass die X/Y-Position einer Zelle mit QTableView::columnViewportPosition(int) und QTableView::rowViewportPosition(int) abgerufen werden kann. jedoch an der angegebenen Stelle einen Doppelklick mit QTest::mouseDClick(...) weder wählt die Zelle noch setzt sie in den Bearbeitungsmodus:

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

Wie kann ich den Testfall implementieren, die ich oben beschrieben, nur Maus/Tastatur Aktionen verwenden?

PS: Ich versuche, das unter Windows XP 32 Bit und Qt 4.6.1

Antwort

5

Es gibt mehrere Dinge zu beachten, wenn sie in einem QTableView durch simulierte Ereignisse zu bearbeiten versuchen:

A QTableView nicht Anzeige seiner Zellen direkt, es tut das mit seiner viewport(). Ebenso muss das Doppelklickereignis an das Ansichtsfenster anstatt an die Tabellenansicht selbst gesendet werden.

Wenn Sie jetzt

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

die Zelle ausgewählt werden, aber nicht im Bearbeitungsmodus (im Gegensatz zu einem Menschen initiierten Doppelklick, die sofort in der Zelle in dem Bearbeitungsmodus versetzt, selbst wenn die View-Tabelle nicht hatten Fokus vorher). Wenn Sie jedoch vor dem Doppelklick einen einzigen Klick auf den gleichen Ort hinzufügen, wird es funktionieren!

Wenn Sie dann den Tastendruck [Ende] an das Ansichtsfenster gesendet haben, springt der Cursor nicht zum Ende des Tabellenzelleninhalts, sondern die letzte Zelle in der aktuellen Zeile wird ausgewählt.
Um den Inhalt der Tabellenzelle zu ändern, müssen Sie das Ereignis stattdessen an das aktuelle Editor-Widget senden. Der einfachste Weg, das zu tun, ist die Verwendung von QWidget::focusWidget()

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

Beachten Sie, dass es so mit, obwohl als focusWidget unsicher sein kann() kann NULL zurückgeben.


Mit diesem Wissen kann der Testfall wie folgt programmiert werden:

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

(Hinweis: Wenn Sie dies überprüfen möchten, können Sie QTest :: qWait (1000) Befehle nach jedem hinzufügen Ereignis)


Wenn Sie die _data verwenden() als here beschrieben, beachten Sie, dass Sie die focusWidget nicht abgerufen werden können() zum Zeitpunkt der Datenerstellung. Ich löste dieses Problem, indem ich eine benutzerdefinierte Schnittstelle ITestAction mit nur einer reinen virtuellen Funktion "execute()" erstellte. Ich fügte dann Unterklassen mit einem ähnlichen Konstruktor hinzu wie die QTest::mouseClick(...) etc Funktionen. Diese Klassen rufen einfach die QTest-Funktionen auf, verwenden aber abhängig von einem zusätzlichen booleschen Flag entweder das Widget selbst oder sein Fokus-Widget als Parameter. Der Slot _data() speichert dann eine QList < ITestAction *> für jede Datenzeile, und der tatsächliche Testschlitz iteriert über diese Liste und ruft execute() für jedes Element auf, bevor die Validierung durchgeführt wird.

+0

Dies ist genau die Antwort, die ich brauchte, vielen Dank :) – astrojuanlu

+0

Was ist die + 5 und + 10 für in - int xPos = m_pTableView-> columnViewportPosition (2) + 5; int yPos = m_pTableView-> rowViewportPosition (3) + 10; – NiladriBose

+1

@NiladriBose: Dies sind Zahlen von Pixeln. Da wir Klicks simulieren, möchten wir wahrscheinlich irgendwo in die Zelle klicken, nicht auf den Rand, nur um sicher zu gehen, dass die richtige Zelle ausgewählt wird. –