Как получить указатель на всплывающее диалоговое окно в Qt, которое блокирует поток пользовательского интерфейса в QTest - PullRequest
0 голосов
/ 10 июня 2018

Я пишу интеграционный тест с использованием QTest, в котором, как только я щелкаю в окне просмотра виджета, появляется многострочное всплывающее окно QInputDialog, которое блокирует дальнейшее выполнение кода и требует ручной отмены диалога.Вот код:

void PartTest::testTypewriterAnnotTool()
{
    Okular::Part part(nullptr, nullptr, QVariantList()); // It is the main widget of PDF reader comprising of viewport where PDF page is shown

    part.openUrl(QUrl::fromLocalFile(QStringLiteral(KDESRCDIR "data/file1.pdf"))); // open file1.pdf

    part.widget()->show();
    QVERIFY(QTest::qWaitForWindowExposed(part.widget()));

    // Width and height of pageView widget, the child of Part widget which shows the PDF page

    const int width = part.m_pageView->horizontalScrollBar()->maximum() +
                      part.m_pageView->viewport()->width();
    const int height = part.m_pageView->verticalScrollBar()->maximum() +
                       part.m_pageView->viewport()->height();

    part.m_document->setViewportPage(0); // sets viewport page 0, i.e. page number 1

    QMetaObject::invokeMethod(part.m_pageView, "slotToggleAnnotator", Q_ARG( bool, true )); // toggles and shows the annotation toolbar with all tools avaialable

    QList<QToolButton *> toolbuttonList = part.m_pageView->findChildren<QToolButton *>(); // find a list of annotation toolbutton
    // Check if the tooltip of 10th button is "Typewriter"
    QToolButton* typewriterButton = toolbuttonList.at(9);
    QCOMPARE( typewriterButton->toolTip(), QStringLiteral("Typewriter") );

    typewriterButton->click(); // clicking and selecting typewriter annotation tool

    QTest::mouseMove(part.m_pageView->viewport(), QPoint(width * 0.5, height * 0.2)); // leading mouse pointer to a specific point in the viewport

    QTest::mouseClick(part.m_pageView->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(width * 0.5, height * 0.2)); // mouse left button click on the viewport and a popup dialog with 'add a new note' appears

}

Мне нужно написать контрольный пример, в котором я должен взять всплывающее диалоговое окно и программно закрыть его.Я пытаюсь добиться этого, используя QTimer, где я выполню функцию для захвата диалога после 1 секунды щелчка в окне просмотра и затем пытаюсь закрыть его так:

class PartTest
{
...
private:
    Okular::part *m_part;
}

void PartTest::testTypewriterAnnotTool()
{
...
    m_part = &part;
    QTimer* mTimer = new QTimer(this);
    mTimer->setSingleShot(true);
    connect(mTimer, SIGNAL(timeout()), SLOT(testDialogClosed()));
    mTimer->start(1000);
    QTest::mouseClick(part.m_pageView->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(width * 0.5, height * 0.2));
}

void PartTest::testDialogClosed()
{
    bool m_clicked = false;
    QDialog *dialog = m_part->widget()->findChild<QDialog*>();
    if (dialog)
    {
        QDialogButtonBox *buttonBox = dialog->findChild<QDialogButtonBox*>();
        buttonBox->button(QDialogButtonBox::Cancel)->click();
        m_clicked = true;
    }
    QVERIFY(m_clicked);
}

Здесь, QVERIFY(m_clicked) контрольный пример всегда «провал», что означает всплывающее окно QInputDialog is not the child of Okular::Part, и я не получаю способ захватить указатель на это диалоговое окно и закрыть его.Любая помощь?

1 Ответ

0 голосов
/ 12 июня 2018

Вы можете перечислить виджеты верхнего уровня и найти диалог следующим образом:

template <class P> QList<P> topLevelWidgets() {
  QList<P> widgets
  for (auto *w : QApplication::topLevelWidgets())
    if (auto *t = qobject_cast<P>(w))
      widgets << t;
  return widgets;
}

template <class P> P topLevelWidget() {
  auto w = topLevelWidgets<P>();
  return (w.size() == 1) ? w.first() : nullptr;
}

void PartTest::testDialogClosed()
{
    bool m_clicked = false;
    if (auto *dialog = topLevelWidget<QDialog*>())
      if (auto *buttonBox = dialog->findChild<QDialogButtonBox*>()) {
        buttonBox->button(QDialogButtonBox::Cancel)->click();
        m_clicked = true;
      }
    QVERIFY(m_clicked);
}
...