Unsolved 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?
-
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().
-
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;
}
} -
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(); -
Are you doing the recording in an event filter ?