4

Qt アプリケーションの基本的な自動化テストを行いたいと考えています。マウス イベントを記録し、ファイルに書き込みます (fe mousepress(300, 400))。自動化を開始すると、ファイルから座標が読み取られ、適切なマウス イベントが送信され、以前に保存されたスクリーンショットとのピクセル比較が行われます。

現在、アプリ全体にまたがり、透過的なマウス イベントを持つオーバーレイ ウィジェットがあります。座標を追跡するだけです。データを読み戻すと、そのオーバーレイはマウスが押された位置に長方形を描画します。Qt のイベント システムに mousePressEvents を送信するときに助けが必要です。正しい位置にポイントを描画しますが、実際に物理的なクリックを行うことはありません。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();
}
4

2 に答える 2