Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Qt自动UI测试因messagebox而停止。如何在messagebox上模拟输入?_C++_Qt_User Interface_Testing_Automated Tests - Fatal编程技术网

C++ Qt自动UI测试因messagebox而停止。如何在messagebox上模拟输入?

C++ Qt自动UI测试因messagebox而停止。如何在messagebox上模拟输入?,c++,qt,user-interface,testing,automated-tests,C++,Qt,User Interface,Testing,Automated Tests,我的任务是为正在开发的软件编写一个自动化的UI测试。发生这种情况时,会有单选按钮触发messagebox,它会停止我的自动测试,直到我手动确认它(按ENTER键)。问题是我不知道如何调用新调用的messagebox,然后通过QTest::keyClick(,QtKey::Key\u Enter)确认它并让我的自动测试继续运行 我正在使用QWidgets、QApplication、Q_对象和QtTest。 我将提供与我正在使用的代码类似的代码: void testui1(){ Form1* myf

我的任务是为正在开发的软件编写一个自动化的UI测试。发生这种情况时,会有单选按钮触发messagebox,它会停止我的自动测试,直到我手动确认它(按ENTER键)。问题是我不知道如何调用新调用的messagebox,然后通过
QTest::keyClick(,QtKey::Key\u Enter)确认它并让我的自动测试继续运行

我正在使用QWidgets、QApplication、Q_对象和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]类型,因此我不需要它返回我是否按了Yes或No。方法需要知道它应该按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);
    }
}
QWidgetList allToplevelWidgets=QApplication::topLevelWidgets();
foreach(QWidget*w,allToplevelWidgets){
如果(w->inherits(“QMessageBox”)){
QMessageBox*mb=qobject_cast(w);
QTest::keyClick(mb,Qt::Key\u Enter);
}
}

问题在于,一旦“单击”单选按钮,导致调用
QMessageBox::exec
,代码就会停止运行,直到用户单击其中一个按钮

通过在单击单选按钮之前启动计时器,可以模拟用户单击按钮

在计时器的回调函数中,您可以使用该函数获取指向消息框的指针,然后只需对其调用
close

QTimer::singleShot(0, [=]()
    {
        QWidget* widget = QApplication::activeModalWidget();
        if (widget)
            widget->close();
    });
如果要按消息框上的特定键,可以使用向消息框发布键事件

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 modal\n";
                    }
                });

            QMessageBox(
                QMessageBox::Icon::Warning,
                "Are you sure?",
                "Are you sure?",
                QMessageBox::Yes | QMessageBox::No,
                &window).exec();
        });

    window.show();
    return app.exec();
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,字符**argv)
{
QApplication应用程序(argc、argv);
qmain窗口;
QWidget小部件;
setCentralWidget(&widget);
QHBoxLayout布局(和小部件);
QPushButton btn(“go”);
layout.addWidget(&btn);
QObject::connect(&btn,&QPushButton::单击,[&]()
{
QTimer::单次快照(0,[=]()
{
QWidget*widget=QApplication::activeModalWidget();
如果(小部件)
{
窗口小部件->关闭();
}
其他的
{

std::你的代码能找到消息框吗?请澄清。我怀疑它能找到。在任何情况下,是否有一段脚本可以找到该消息框?你的代码看起来有效:迭代所有顶级窗口。我可能怀疑模式消息框阻塞了事件循环,因此在消息框打开时你的代码不会执行。我相信你需要要注册一个将关闭消息框的计时器-请参见下面对我的答案所做的编辑谢谢你的朋友!但是在文章
QTimer::singleShot(0,[=])中
应该用等待时间的值替换0。在我的例子中,我将150作为毫秒值放入其中。它可以工作!@Unit1添加任意延迟非常脆弱且容易出错-150ms在您的开发机器上对您有效,但它能在每台机器上工作吗?我会坚持延迟0,但添加对
QCoreApplication::proces的调用sEvents();
在检查活动模式(未测试,只是一个想法,如果它有效,将远优于使用延迟)之前,延迟=0对我不起作用。调试脚本已停止。我在将延迟设置为150毫秒之前对其进行了测试。|您建议我将
QCoreApplication::processEvents()放置在何处
?在鼠标单击调用messagebox之前,或在该QTimer内?@Unit1在调用获取活动模式前的计时器内。
QCoreApplication::processEvents();
无效。我确实将其放在了activemodalwidget之前。消息框再次出现并停止了自动化。