Qt Event Replay



  • I'm trying to replay stored events using QApplication::postEvent(). To do this you need to know what QObject to send the event to. This is information that will need to be serialized along with the QEvent information. One way to do this is to assign names to all the objects in the program by calling QObject::setObjectName(). The issue with this method is that it doesn't like to play nice with QTableView when editing cells or QTreeWidget for drag and drop. It appears the event replay works well with other objects. Do you recommend another way to find the correct widget to send the events to?


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    How are you currently "recording" these events ?



  • I'm creating deep copies of the events and storing them in a vector and replaying the events via postEvent().


  • Lifetime Qt Champion

    Then how do you make these copies ?



  • unique_ptr<QEvent> copyEvent(const QEvent * ev) {
    unique_ptr<QEvent> eventCopy;

    if(dynamic_cast<const QMouseEvent *>(ev)) {
      eventCopy = make_unique<QMouseEvent>(
        static_cast<const QMouseEvent&>(*ev));
    }
    else if(dynamic_cast<const QContextMenuEvent *>(ev)) {
      eventCopy = make_unique<QContextMenuEvent>(
        static_cast<const QContextMenuEvent&>(*ev));  
    }
    else if(dynamic_cast<const QTabletEvent *>(ev)) {
      eventCopy = make_unique<QTabletEvent>(
        static_cast<const QTabletEvent&>(*ev));  
    }
    else if(dynamic_cast<const QDropEvent *>(ev)) {
      eventCopy = make_unique<QDropEvent>(
        static_cast<const QDropEvent&>(*ev));  
    }
    else if(dynamic_cast<const QDragEnterEvent *>(ev)) {
      eventCopy = make_unique<QDragEnterEvent>(
        static_cast<const QDragEnterEvent&>(*ev));  
    }
    else if(dynamic_cast<const QDragLeaveEvent *>(ev)) {
      eventCopy = make_unique<QDragLeaveEvent>(
        static_cast<const QDragLeaveEvent&>(*ev));  
    }
    else if(dynamic_cast<const QDragMoveEvent *>(ev)) {
      eventCopy = make_unique<QDragMoveEvent>(
        static_cast<const QDragMoveEvent&>(*ev));  
    }
    
    return eventCopy;
    

    }
    }


  • Lifetime Qt Champion

    And where exactly are you calling that code in your application ?



  • void UIEventRecorder::replayEvent(void) {
    const UIEvent& ithEvent = recordedEvents[replayRecordedEventIndex++];

    QStringList path = QString::fromStdString(ithEvent.getObjectName()).
    split("/", QString::KeepEmptyParts);

    if(path.isEmpty()) {
    return;
    }

    QList<QObject*> objects = mainWndHandle->findChildren<QObject*>(path.last());

    for(const auto& it: objects) {
    if(it->metaObject()->className() == ithEvent.getClassName()
    && UIUtil::getObjectPathName(it) == ithEvent.getObjectName()) {

      // this will post the event to replay and won't block
      qApp->postEvent(it, copyEvent(ithEvent.getEvent()).release());
      break;
    }
    

    }

    // we replayed all the events
    // let's return
    if(replayRecordedEventIndex >= recordedEvents.size()) {
    replayRecordedEventIndex = 0;
    return;
    }

    // time between events
    int delta = recordedEvents[replayRecordedEventIndex].getTimeOffset() -
    recordedEvents[replayRecordedEventIndex - 1].getTimeOffset();

    // set the interval to call the next event
    timer->setInterval(delta > 0 ? delta : 0);
    timer->start();


  • Lifetime Qt Champion

    Are you doing the recording in an event filter ?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.