我的任务是为正在开发的软件编写一个自动化的UI测试。碰巧,有单选按钮触发一个消息框,它会停止我的自动测试,直到我手动确认它(按 ENTER)。问题是我不知道如何调用新调用的消息框,然后由QTest::keyClick(<object>, QtKey::Key_Enter);
确认并让我的自动测试继续运行。
我正在使用QWidgets,QApplication,Q_OBJECT和QtTest。 我将提供一个类似于我正在使用的代码:
void testui1(){
Form1* myform = new Form1();
myform->show();
QTest::mouseClick(myform->radioButton01, Qt::LeftButton, Qt::NoModifier, QPoint(), 100);
// Message box pops up and stops the operation until confirmed
QTest::mouseClick(myform->radioButton02, Qt::LeftButton, Qt::NoModifier, QPoint(), 100);
// again
...
}
如何编写脚本以自动确认消息框?消息框只是一个 [OK] 类型,因此无论我按了"是"还是"否",我都不需要它返回。QTest::keyClick(<target object>, Qt::Key_Enter)
方法需要知道它应该按回车键到哪个对象。我尝试将myform
包含在对象中,但它不起作用。谷歌搜索我没有找到答案。我发现以下结果不适用于我正在寻找的内容
QWidgetList allToplevelWidgets = QApplication::topLevelWidgets();
foreach (QWidget *w, allToplevelWidgets) {
if (w->inherits("QMessageBox")) {
QMessageBox *mb = qobject_cast<QMessageBox *>(w);
QTest::keyClick(mb, Qt::Key_Enter);
}
}
问题是,一旦你"点击"了单选按钮,这会导致QMessageBox::exec
被调用,你的代码就会停止运行,直到用户点击按钮。
您可以通过在单击单选按钮之前启动计时器来模拟用户单击按钮。
在计时器的回调函数中,可以使用QApplication::activeModalWidget()
获取指向消息框的指针,然后只需对其调用close
。
QTimer::singleShot(0, [=]()
{
QWidget* widget = QApplication::activeModalWidget();
if (widget)
widget->close();
});
如果要按消息框上的特定键,可以使用QCoreApplication::postEvent
将键事件发布到消息框
QTimer::singleShot(0, [=]()
{
int key = Qt::Key_Enter; // or whatever key you want
QWidget* widget = QApplication::activeModalWidget();
if (widget)
{
QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier);
QCoreApplication::postEvent(widget, event);
}
});
因此,就这如何与您给出的示例代码相关联而言:
void testui1()
{
Form1* myform = new Form1();
myform->show();
QTimer::singleShot(0, [=]()
{
QWidget* widget = QApplication::activeModalWidget();
if (widget)
widget->close();
else
QFAIL("no modal widget");
});
QTest::mouseClick(myform->radioButton01, Qt::LeftButton, Qt::NoModifier, QPoint(), 100);
}
将上述所有内容组合在一起的示例应用:
#include <QApplication>
#include <QMainWindow>
#include <QHBoxLayout>
#include <QPushButton>
#include <QTimer>
#include <QMessageBox>
#include <iostream>
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QMainWindow window;
QWidget widget;
window.setCentralWidget(&widget);
QHBoxLayout layout(&widget);
QPushButton btn("go");
layout.addWidget(&btn);
QObject::connect(&btn, &QPushButton::clicked, [&]()
{
QTimer::singleShot(0, [=]()
{
QWidget* widget = QApplication::activeModalWidget();
if (widget)
{
widget->close();
}
else
{
std::cout << "no active modaln";
}
});
QMessageBox(
QMessageBox::Icon::Warning,
"Are you sure?",
"Are you sure?",
QMessageBox::Yes | QMessageBox::No,
&window).exec();
});
window.show();
return app.exec();
}
单击Go
看起来什么都没发生,因为QMessageBox
会立即关闭。
若要证明消息框显示然后关闭,可以增加调用中QTimer::singleShot
的时间,例如1000
。现在它将显示消息框 1 秒,然后由计时器关闭。