我想對我的Qt應用程序做一個基本的自動化測試。它記錄鼠標事件並將它們寫入文件(f.e. mousepress(300,400))。當開始自動化時,它從文件讀取座標,發送適當的鼠標事件,並與先前保存的屏幕截圖進行像素比較。如何通過將事件發佈到Qt事件系統來模擬鼠標點擊?
目前,我有一個覆蓋小部件,跨越應用程序,並有透明的鼠標事件。它所做的就是跟蹤座標。 重新讀取數據時,該覆蓋圖會在鼠標按下位置繪製一個矩形。 發送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();
}
這可能無法完全解決這個問題,但是,您提交MouseButtonPress的事件,但你缺少一個相應的MouseButtonRelease。另外,我建議不要循環並等待事件完成,而應該爲每個事件使用單個QTimer,並讓主循環繼續運行,而不要求助於調用processEvents。 – TheDarkKnight
謝謝,我試圖發佈一個額外的MouseButtonRelease事件,但沒有奏效。 – user2246120
我不太清楚我的理解你的QTimer的想法。 QTimer :: singleShot(0,receiver,SlotSendEvent());無法將座標傳遞給插槽。你是什麼意思? – user2246120