如何发送人工 QKeyEvent 到 QWebEngineView?
How to send artificial QKeyEvent to QWebEngineView?
上下文:我正在创建一个带有自定义屏幕键盘的小型网络浏览器。
它在 Qt WebKit 上几乎可以正常工作(QWeb*
类)但是有一些崩溃归因于 WebKit 中的错误...在 Qt 5.4.0 之后不会被修复,因为它们正在转向 Qt WebEngine。
所以我决定按照简短的 webkit->webengine 转换指南将这些东西移动到 Qt WebEngine (QWebEngine*
类)。
在 QWebElement
上的警告部分之后,我已经解决了 showing/hiding 屏幕键盘(现在需要 运行 async.JS 代码)。
但我正在摸索如何将人工按键事件发送到网页。
我已经尝试了一些东西:
QCoreApplication::postEvent(m_webview, event)
在使用旧的 QWeb
东西时什么都不做;
- 可以通过 运行 JavaScript 发送密钥,但我觉得这太脏了
谢谢,
我想现在实现这一目标的唯一可能性是
利用 QAction
将事件发送到 WebView,例如使用类似的东西:
connect( this , SIGNAL( keyPressed( int ) ) , &m_webview , SLOT( handleKey( int ) ) );
我想该功能将添加到 Qt 5.5.1 中,如下所示:
尽管最初的问题已经存在一年了,但对于那些像我一样决定(终于!)从 QWebKit 迁移到 QWebEngine (Qt 5.5 - 5.6b) 的人来说仍然是现实的。这是一个肮脏的解决方案,需要现有的 webenginepage->view()。这是针对鼠标事件的,如果它不是针对键盘事件,那就不足为奇了:
void Whatever::sendMouseEvent( QObject* targetObj, QMouseEvent::Type type, const QPoint& pnt ) const
{
QMouseEvent event( type, pnt, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier );
QApplication::sendEvent( targetObj, &event );
}
void Whatever::sendMouseClick( QObject* targetObj, const QPoint& pnt ) const
{
sendMouseEvent( targetObj, QMouseEvent::MouseMove, pnt );
sendMouseEvent( targetObj, QMouseEvent::MouseButtonPress, pnt );
sendMouseEvent( targetObj, QMouseEvent::MouseButtonRelease, pnt );
}
void Whatever::emulateMouseClick( const QPoint& pnt ) const
{
//-- right now (Qt 5.5 & 5.6) there is only one child -
//-- QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget
//-- but it could change in future
Q_FOREACH( QObject* obj, mWebEnPage->view()->children() ) //-- ACHTUNG! Check mWebEnPage->view() in real code!
if( qobject_cast<QWidget*>( obj ) )
sendMouseClick( obj, pnt );
}
灵感来自
和
和谷歌搜索。
这段代码工作正常
for(auto* child : ui->webEngineView->children() ) {
int key = Qt::Key_V; //or some other
QKeyEvent pressEvent = QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier, QKeySequence(key).toString());
QKeyEvent releaseEvent = QKeyEvent(QEvent::KeyRelease, key, Qt::NoModifier);
qApp->sendEvent(child, &pressEvent);
qApp->sendEvent(child, &releaseEvent);
}
上下文:我正在创建一个带有自定义屏幕键盘的小型网络浏览器。
它在 Qt WebKit 上几乎可以正常工作(QWeb*
类)但是有一些崩溃归因于 WebKit 中的错误...在 Qt 5.4.0 之后不会被修复,因为它们正在转向 Qt WebEngine。
所以我决定按照简短的 webkit->webengine 转换指南将这些东西移动到 Qt WebEngine (QWebEngine*
类)。
在 QWebElement
上的警告部分之后,我已经解决了 showing/hiding 屏幕键盘(现在需要 运行 async.JS 代码)。
但我正在摸索如何将人工按键事件发送到网页。
我已经尝试了一些东西:
QCoreApplication::postEvent(m_webview, event)
在使用旧的QWeb
东西时什么都不做;- 可以通过 运行 JavaScript 发送密钥,但我觉得这太脏了
谢谢,
我想现在实现这一目标的唯一可能性是
利用 QAction
将事件发送到 WebView,例如使用类似的东西:
connect( this , SIGNAL( keyPressed( int ) ) , &m_webview , SLOT( handleKey( int ) ) );
我想该功能将添加到 Qt 5.5.1 中,如下所示:
尽管最初的问题已经存在一年了,但对于那些像我一样决定(终于!)从 QWebKit 迁移到 QWebEngine (Qt 5.5 - 5.6b) 的人来说仍然是现实的。这是一个肮脏的解决方案,需要现有的 webenginepage->view()。这是针对鼠标事件的,如果它不是针对键盘事件,那就不足为奇了:
void Whatever::sendMouseEvent( QObject* targetObj, QMouseEvent::Type type, const QPoint& pnt ) const
{
QMouseEvent event( type, pnt, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier );
QApplication::sendEvent( targetObj, &event );
}
void Whatever::sendMouseClick( QObject* targetObj, const QPoint& pnt ) const
{
sendMouseEvent( targetObj, QMouseEvent::MouseMove, pnt );
sendMouseEvent( targetObj, QMouseEvent::MouseButtonPress, pnt );
sendMouseEvent( targetObj, QMouseEvent::MouseButtonRelease, pnt );
}
void Whatever::emulateMouseClick( const QPoint& pnt ) const
{
//-- right now (Qt 5.5 & 5.6) there is only one child -
//-- QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget
//-- but it could change in future
Q_FOREACH( QObject* obj, mWebEnPage->view()->children() ) //-- ACHTUNG! Check mWebEnPage->view() in real code!
if( qobject_cast<QWidget*>( obj ) )
sendMouseClick( obj, pnt );
}
灵感来自
这段代码工作正常
for(auto* child : ui->webEngineView->children() ) {
int key = Qt::Key_V; //or some other
QKeyEvent pressEvent = QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier, QKeySequence(key).toString());
QKeyEvent releaseEvent = QKeyEvent(QEvent::KeyRelease, key, Qt::NoModifier);
qApp->sendEvent(child, &pressEvent);
qApp->sendEvent(child, &releaseEvent);
}