有什么方法可以将拖放事件转发到嵌入式流程窗口?

时间:2017-02-16 16:53:24

标签: c++ windows qt webview pyqt

一些背景知识:

我需要在Qt应用程序(嵌入python / PyQt)中嵌入某种webview以显示一些html内容。我坚持使用Qt的MinGW构建,因为这是我们的软件的Windows版本,并且不可能迁移到Visual C ++。对我来说不幸的是,QtWebKit已从Qt的最新版本中删除,并且Qt的MinGW版本不支持其替换QtWebEngine

看来我剩下的选项是

之一
  • 维护Qt的自定义构建,重新包含旧的QtWebKit代码。
  • 嵌入其他渲染引擎。
  • 在单独的流程中启动Web浏览器,并将其窗口嵌入主程序中。

我已经研究了前两个选项,这两个选项听起来像一个PITA,结合了过时/废弃的代码,以及复杂的构建过程,包含补丁/过时/冲突的文档,以及有限的Windows支持。

我决定探索将Web浏览器进程嵌入到我的应用程序中的选项。我使用QWindow::fromWinIdQWidget::createWindowContainer

成功地在PyQt中嵌入了一个firefox进程
self.process = QtCore.QProcess()
self.process.setProgram('C:/Program Files (x86)/Mozilla Firefox/firefox.exe')
self.process.start()

time.sleep(1)
hwnd = get_window_handle(self.process.processId())

ext_win = QtGui.QWindow.fromWinId(hwnd)
widget = QtWidgets.QWidget.createWindowContainer(ext_win)
widget.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.ForeignWindow)
self.layout().addWidget(widget)

我可以将html文件拖放到嵌入式firefox窗口中,然后加载就好了。我以为我可以通过伪造拖放事件来利用此功能,以便以编程方式加载文件。

def fakeDragDropEvent(self, urls):
    point = QtCore.QPoint(self.width()/2, self.height()/2)

    self.mimedata = QtCore.QMimeData()
    self.mimedata.setUrls(urls)

    dragevent = QtGui.QDragEnterEvent(point, QtCore.Qt.CopyAction, self.mimedata, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier)
    app.postEvent(self, dragevent)

    time.sleep(0.1)

    dropevent = QtGui.QDragEnterEvent(point, QtCore.Qt.CopyAction, self.mimedata, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier)
    app.postEvent(self, dropevent)

当我实现事件处理程序并设置acceptDrops(True)时,主窗口等可以拾取这些虚假事件,但它们似乎对嵌入式进程窗口没有影响。

有没有办法让我的嵌入式流程窗口获取这些事件?或者我是否需要使用本机Windows API对拖放事件进行编程?

我也对我在应用程序中如何显示html的任何其他建议持开放态度。

0 个答案:

没有答案