首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有委托和自定义模型的QtTest表视图

带有委托和自定义模型的QtTest表视图
EN

Stack Overflow用户
提问于 2021-12-03 11:04:23
回答 1查看 160关注 0票数 2

我正在尝试使用自定义模型和几个委托(combobox和spinbox)测试QTableView

Init测试用例

代码语言:javascript
复制
void TestGuiDelegateWithTableView::initTestCase()
{
    user_data_t d{{"foo", 2}, {"bar", 4}, {"baz", 6}};
    table = new QTableView;
    table->setModel(new Model);
    table->setItemDelegateForColumn(0, new DelegateCombobox(std::move(d)));
    table->setItemDelegateForColumn(1, new DelegateSpinbox({-10., 10.}));
}

带有用户数据的组合框

Combobox委托有一个构造函数,它接受std::vector<std::pair<QString, int>>、显示和用户角色值的集合。

代码语言:javascript
复制
    QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override
    {
        auto* box{new QComboBox(parent)};
        for (const auto& [text, user] : _data) {
            box->addItem(text, user);
        }
        return box;
    }

测试_data方法工作得很完美(或者是简单的巧合):

代码语言:javascript
复制
    QTest::addColumn<QTestEventList>("events");
    QTest::addColumn<QString>("display");
    QTest::addColumn<int>("user");

    const auto cell = table->model()->index(0, 0);
    const auto center = table->visualRect(cell).center();

    {
        QTestEventList events;
        events.addMouseClick(Qt::LeftButton, Qt::NoModifier, center, 50);
        events.addMouseDClick(Qt::LeftButton, Qt::NoModifier, center, 100);
        events.addKeyPress(Qt::Key_Down);
        events.addKeyPress(Qt::Key_Enter);
        QTest::newRow("e1") << events << "foo" << 2;
    }

但是,当我试图实现第二个或第三个组合框元素时,如下所示:

代码语言:javascript
复制
    {
        QTestEventList events;
        events.addMouseClick(Qt::LeftButton, Qt::NoModifier, center, 50);
        events.addMouseDClick(Qt::LeftButton, Qt::NoModifier, center, 100);
        events.addKeyPress(Qt::Key_Down, Qt::NoModifier, 10);
        events.addKeyPress(Qt::Key_Down, Qt::NoModifier, 10);
        events.addKeyPress(Qt::Key_Enter);
        QTest::newRow("e2") << events << "bar" << 4;
    }

    {
        QTestEventList events;
        events.addMouseClick(Qt::LeftButton, Qt::NoModifier, center, 50);
        events.addMouseDClick(Qt::LeftButton, Qt::NoModifier, center, 100);
        events.addKeyPress(Qt::Key_Down);
        events.addKeyPress(Qt::Key_Down);
        events.addKeyPress(Qt::Key_Down);
        events.addKeyPress(Qt::Key_Enter);
        QTest::newRow("e3") << events << "baz" << 6;
    }

它不管用。

呼叫代码:

代码语言:javascript
复制
{
    QFETCH(QTestEventList, events);
    QFETCH(QString, display);
    QFETCH(int, user);

    QVERIFY2(table->viewport(), "Should be not empty");
    events.simulate(table->viewport());
    QCOMPARE(table->model()->index(0, 0).data(Qt::DisplayRole).toString(), display);
    QCOMPARE(table->model()->index(0, 0).data(Qt::UserRole).toInt(), user);
}

带量程的尖头箱

我还在试着测试菠萝盒:

代码语言:javascript
复制
    QVERIFY2(table, "Should be not empty");
    QVERIFY2(table->model(), "Should be not empty");

    const auto cell = table->model()->index(0, 1);
    const auto center = table->visualRect(cell).center();
    QTest::mouseClick(table->viewport(), Qt::LeftButton, Qt::NoModifier, center);
    QTest::mouseDClick(table->viewport(), Qt::LeftButton, Qt::NoModifier, center);
    QTest::keyClicks(table->viewport()->focusWidget(),"-9.54");
    QTest::keyPress(table->viewport()->focusWidget(), Qt::Key_Enter);

    const auto actual = table->model()->index(0, 1).data(Qt::DisplayRole).toString();
    QCOMPARE(actual, "-9.54");

模型

设定数据

代码语言:javascript
复制
    bool setData(const QModelIndex& index, const QVariant& value, int role) override
    {
        if (const auto col = index.column(); col == 0) {
            if (const auto row = index.row(); role == Qt::DisplayRole) {
                _display[row] = value.toString();
                return true;
            }
            else if (role == Qt::UserRole) {
                _user[row] = value.toInt();
                return true;
            }
        } else if (col == 1) {
            if (role == Qt::DisplayRole) {
                _spin[index.row()] = value.toDouble();
                return true;
            }
        }
    return false;
    }

数据()

代码语言:javascript
复制
    [[nodiscard]] QVariant data(const QModelIndex& index, int role) const override
    {
        if (const auto col = index.column(); col == 0) {
            if (const auto row = index.row(); role == Qt::DisplayRole) {
                return _display[row];
            }
            else if (role == Qt::UserRole) {
                return _user[row];
            }
        } else if (col == 1 && role == Qt::DisplayRole) {
            return _spin[index.row()];
        }

        return {};
    }

私有存储字段:

代码语言:javascript
复制
  private:
    std::array<QString, 3> _display{};
    std::array<int, 3> _user{};
    std::array<double, 3> _spin{};

、PS、示例在文档和internet中没有涵盖Qt框架的mvc模式中的委托。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-13 09:12:48

来自源代码的解决方案

在研究了qtbase 源代码测试用例之后,我发现有必要使用QCoreApplication::processEvents()函数。

组合框

试验数据

代码语言:javascript
复制
void TestGuiDelegateWithTableView::not_empty_cell2_data()
{
    QTest::addColumn<int>("index");
    QTest::addColumn<QString>("display");
    QTest::addColumn<int>("user");

    QTest::newRow("foo 2") << 0 << "foo" << 2;
    QTest::newRow("bar 4") << 1 << "bar" << 4;
    QTest::newRow("baz 6") << 2 << "baz" << 6;
}

试验体

代码语言:javascript
复制
void TestGuiDelegateWithTableView::not_empty_cell2()
{
    QVERIFY2(table, "Should be not empty");
    const auto cell = table->model()->index(0, 0);
    const auto center = table->visualRect(cell).center();

    // begin common trash
    auto* viewport = table->viewport();
    QVERIFY2(viewport, "Should be not empty");
    QTest::mouseClick(viewport, Qt::LeftButton, Qt::KeyboardModifiers(), center);
    QTest::mouseDClick(viewport, Qt::LeftButton, Qt::KeyboardModifiers(), center);
    QVERIFY2(viewport->focusWidget(), "Should be not empty");
    // end common trash

    QFETCH(int, index);
    for (auto i = 0; i < index; ++i) QTest::keyPress(viewport->focusWidget(), Qt::Key_Down);
    QTest::keyPress(viewport->focusWidget(), Qt::Key_Enter);
    QCoreApplication::processEvents(); // <-- here is important

    QFETCH(QString, display);
    QFETCH(int, user);
    const auto actual_display = table->model()->index(0, 0).data(Qt::DisplayRole).toString();
    const auto actual_user = table->model()->index(0, 0).data(Qt::UserRole).toInt();
    QCOMPARE(display, actual_display);
    QCOMPARE(user, actual_user);
}

尖头箱

试验数据

代码语言:javascript
复制
void TestGuiDelegateWithTableView::spinbox_data()
{
    QTest::addColumn<double>("user_input");
    QTest::newRow("-10.0") << -10.;
    QTest::newRow("+10.0") <<  10.;
    QTest::newRow("0.0")   <<  0.0;
}

试验体

代码语言:javascript
复制
void TestGuiDelegateWithTableView::spinbox()
{
    QVERIFY2(table, "Should be not empty");
    QVERIFY2(table->model(), "Should be not empty");

    QFETCH(double , user_input);

    const auto cell = table->model()->index(0, 1);
    const auto center = table->visualRect(cell).center();
    QTest::mouseClick(table->viewport(), Qt::LeftButton, Qt::NoModifier, center);
    QTest::mouseDClick(table->viewport(), Qt::LeftButton, Qt::NoModifier, center);
    QTest::keyClicks(table->viewport()->focusWidget(), QString::number(user_input, 'g', 6));
    QTest::keyPress(table->viewport()->focusWidget(), Qt::Key_Enter);
    QCoreApplication::processEvents(); // here

    const auto actual = table->model()->index(0, 1).data(Qt::DisplayRole).toDouble();
    QVERIFY(qFuzzyCompare(actual, user_input));
}

注意:

在Qt源代码中,有以下几行:

代码语言:javascript
复制
#if defined(Q_OS_UNIX)
    QCoreApplication::processEvents();
#endif
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70213296

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档