Я хотел бы провести элементарный тест автоматизации моего приложения Qt. Он записывает события мыши и записывает их в файл (например, mousepress(300, 400)). При запуске автоматизации он считывает координаты из файла, отправляет соответствующие события мыши и выполняет сравнение пикселей с ранее сохраненным скриншотом.
В настоящее время у меня есть оверлейный виджет, который охватывает приложение и имеет прозрачные события мыши. Все, что он делает, это отслеживает координаты. При обратном считывании данных это наложение рисует прямоугольник в месте нажатия мыши. Мне нужна помощь при отправке mousePressEvents в систему событий Qt. Он рисует точки в правильном месте, но никогда не делает физический щелчок. Есть ли способ сделать это с помощью Qt или мне придется использовать Window SendInput()?
Есть ли способ сделать паузу и дождаться завершения события мыши? Мне нужно знать, когда событие завершено, чтобы начать сравнение пикселей за пикселем.
Widget::Widget( QWidget *parent )
: QFrame( parent )
, mPoint(QPoint(0,0))
{
setWindowFlags(Qt::WindowStaysOnTopHint);
setStyleSheet("background-color: rgba(0, 0,255, 2%);");
setAttribute(Qt::WA_TransparentForMouseEvents, true);
setGeometry(parent->geometry());
...
}
void Widget::run()
{
QFile file( "coordinates.txt", NULL );
if(!file.open( QIODevice::ReadOnly ))
return;
QTextStream in(&file);
int i = 0;
while (!in.atEnd())
{
QString line = in.readLine();
if(line.startsWith("mousepress"))
{
int startIndex = line.indexOf('(');
int endIndex = line.indexOf(')');
QString coord = line.mid(startIndex+1, line.size() - startIndex - 2);
QStringList nbr = coord.split(',');
mPoint = QPoint(nbr[0].toInt(), nbr[1].toInt());
QWidget *receiver = QApplication::widgetAt(mPoint);
QMouseEvent *event = new QMouseEvent(QEvent::MouseButtonPress, mPoint, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QCoreApplication::postEvent(receiver, event); // same result with sendEvent()
QCoreApplication::processEvents();
update();
// wait till the event finished, then continue with next point
}
}
}
void Widget::paintEvent(QPaintEvent *event)
{
QPainter p( this );
QPen pen;
pen.setBrush(Qt::NoBrush);
if(!mPoint.isNull())
{
pen.setColor(Qt::red);
pen.setWidth( 2 );
p.setPen(pen);
p.drawRoundRect(mPoint.x(), mPoint.y(), 10, 10, 25, 25);
p.drawText(mPoint, QString::number(mPoint.x()) + ", " + QString::number(mPoint.y()));
}
}
[Отредактировано]
Я последовал совету ddriver, и он работает после нескольких изменений: я сохраняю глобальные и локальные позиции в файле для отправки в QMouseEvent.
Как я могу быть уверен, что щелчок мышью завершен, прежде чем делать снимок экрана и сравнивать его с сохраненным изображением?
void Widget::DoStep()
{
if(!mInStream.atEnd())
{
QString line = mInStream.readLine();
if(line.startsWith("MouseButtonPress"))
{
QPoint pos = parseGlobalPos();
QPoint localPos = parseLocalPos();
QWidget *receiver = QApplication::widgetAt(pos);
QMouseEvent *event = new QMouseEvent(QEvent::MouseButtonPress,localPos, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QApplication::postEvent(receiver, event);
QMouseEvent *eventRelease = new QMouseEvent(QEvent::MouseButtonRelease, localPos, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QApplication::postEvent(receiver, eventRelease);
// after successful click, take screenshot and compare them
}
}
if (!mInStream.atEnd())
QMetaObject::invokeMethod(this, "DoStep", Qt::QueuedConnection);
else
file.close();
}