如何从 QTest 单元测试中编辑 QTableView 单元格? [英] How can you edit a QTableView cell from a QTest unit test?

查看:64
本文介绍了如何从 QTest 单元测试中编辑 QTableView 单元格?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 QTestLib 框架.最基本的测试用例之一可以这样描述:

I'm writing a unit test for a custom Validator in a QTableView using the QTestLib framework. One of the most basic test cases could be described like this:

双击第三列第四行的表格单元格,将数字5"附加到其内容中.

Double click the table cell in the third column and the fourth row, and append the number '5' to its content.

仅仅改变模型中的值或任何东西是不够的,测试用例应该像这样执行:

It is not sufficient to simply change the value in the model or anything, the test case shall perform it like this:

  1. 双击表格单元格将其设置为编辑模式
  2. 按 [结束] 键.
  3. 按 [5] 键.

注意:这个问题 有关于如何从代码中将表格单元格设置为编辑模式的答案,但是单元测试应尝试坚持人类用户的可能性,即鼠标/键盘操作.

Note: This question has an answer on how to set a table cell into edit mode from code, however the unit test shall try to stick to the possibilities of a human user, i.e. Mouse/Keyboard actions.

我发现可以使用 QTableView::columnViewportPosition(int)QTableView::rowViewportPosition( int ).但是,使用 QTest::mouseDClick(...) 在指定位置双击 既不选择单元格也不将其设置为编辑模式:

I've found out the X/Y position of a cell can be retrieved using QTableView::columnViewportPosition( int ) and QTableView::rowViewportPosition( int ). However, double clicking at the specified location using QTest::mouseDClick(...) neither selects the cell nor sets it into edit mode:

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

如何仅使用鼠标/键盘操作来实现我上面描述的测试用例?

How can I implement the test case which I described above, using Mouse/Keyboard actions only?

PS:我正在 Windows XP 32 位和 Qt 4.6.1 下尝试这个

PS: I am trying this under Windows XP 32 bit and Qt 4.6.1

推荐答案

尝试通过模拟事件在 QTableView 中进行编辑时需要考虑以下几点:

There are several things to consider when trying to edit in a QTableView through simulated events:

QTableView 不直接显示它的单元格,它使用它的 viewport().同样,双击事件必须发送到视口而不是表格视图本身.

A QTableView does not display its cells directly, it does that using its viewport(). Likewise, the double click event must be sent to the viewport instead of the table view itself.

现在当你这样做

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

单元格将被选中,但不会处于编辑模式(与人为启动的双击不同,即使表格视图之前没有焦点,它也会立即将单元格置于编辑模式).但是,如果您在双击之前在同一位置添加一次单击,它会起作用!

the cell will be selected, but not in edit mode (unlike a human-initiated double click which instantly puts the cell into edit mode even if the table view did not have focus before). If you add a single click on the same location before the double click, however, it will work!

如果您随后将 [End] 按键发送到视口,则光标不会跳转到表格单元格内容的末尾,而是会选择当前行中的最后一个单元格.
为了更改表格单元格内容,您必须将事件发送到当前编辑器小部件.最简单的方法是使用 QWidget::focusWidget()

If you then sent the [End] keypress to the viewport, the cursor would not jump to the end of the table cell content, but instead the last cell in the current row would be selected.
In order to change the table cell content, you must send the event to the current editor widget instead. The easiest way to do that is the usage of QWidget::focusWidget()

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

请注意,像这样使用它可能是不安全的,尽管 focusWidget() 可以返回 NULL.

Note that using it like that can be unsafe though as focusWidget() can return NULL.

有了这些知识,可以按如下方式编写测试用例:

With that knowledge, the test case can be programmed as follows:

// 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) 命令)

(Note: if you want to verify this, you can add QTest::qWait( 1000 ) commands after each event)

如果您使用 此处所述的 _data() 函数,请注意,您无法在数据创建时检索 focusWidget().我通过创建一个自定义接口 ITestAction 解决了这个问题,该接口只有一个纯虚拟的execute()"函数.然后我添加了具有与 QTest::mouseClick(...) etc 函数类似的构造函数的子类.这些类只是调用 QTest 函数,但使用小部件本身或其焦点小部件作为参数,这取决于附加的布尔标志._data() 槽然后存储一个 QList<;ITestAction* > 用于每个数据行,实际的测试槽在执行验证之前迭代该列表并调用每个项目的 execute().

If you are using the _data() functions as described here, note that you cannot retrieve the focusWidget() at the time of data creation. I solved this issue by creating a custom interface ITestAction with only a pure virtual "execute()" function. I then added subclasses with a similar constructor as the QTest::mouseClick(...) etc functions. These classes simply call the QTest functions but use either the widget itself or its focus widget as a parameter, dependent on an additional boolean flag. The _data() slot then stores a QList< ITestAction* > for each data row, and the actual test slot iterates over that list and calls execute() on each item before the validation is performed.

这篇关于如何从 QTest 单元测试中编辑 QTableView 单元格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆