如何使用PyQT5附加和分离外部应用程序或使外部应用程序停靠?

我正在使用ROS开发用于多机器人系统的GUI,但是我在界面中的最后一件事就是冻结:将RVIZ,GMAPPING或其他屏幕嵌入到我的应用程序中。我已经在界面中放置了一个终端,但是无法绕开如何向我的应用程序添加外部应用程序窗口的问题。我知道PyQt5具有createWindowContainer,它使用窗口ID来停靠外部应用程序,但是我没有找到任何示例来帮助我。

如果可能的话,我想在应用程序中将外部窗口拖放到选项卡式框架内。但是,如果这不可能或太难了,那么在单击按钮后仅在选项卡式框架内打开窗口是很好的选择。

我已经尝试打开类似于终端方法的窗口(请参见下面的代码),但是RVIZ窗口在我的应用程序外部打开。

已经尝试使用wmctrl命令将附加/分离的代码转换为linux,但是没有效果。在这里查看我的代码。

也已经尝试过rviz

Python教程,但是我收到了错误消息:

追溯(最近一次调用):导入rviz中的文件“ rvizTutorial.py”,第23行,第19行,“ / opt / ros / indigo / lib

/ python2.7 / dist-packages / rviz /

.py”,在导入librviz_shiboken中ImportError:没有名为librviz_shiboken的模块

#  Frame where i want to open the external Window embedded

self.Simulation = QtWidgets.QTabWidget(self.Base)

self.Simulation.setGeometry(QtCore.QRect(121, 95, 940, 367))

self.Simulation.setTabPosition(QtWidgets.QTabWidget.North)

self.Simulation.setObjectName("Simulation")

self.SimulationFrame = QtWidgets.QWidget()

self.SimulationFrame.setObjectName("SimulationFrame")

self.Simulation.addTab(rviz(), "rViz")

# Simulation Approach like Terminal

class rviz(QtWidgets.QWidget):

def __init__(self, parent=None):

super(rviz, self).__init__(parent)

self.process = QtCore.QProcess(self)

self.rvizProcess = QtWidgets.QWidget(self)

layout = QtWidgets.QVBoxLayout(self)

layout.addWidget(self.rvizProcess)

# Works also with urxvt:

self.process.start('rViz', [str(int(self.winId()))])

self.setGeometry(121, 95, 940, 367)

回答:

我尚未对此进行专门测试,因为我的Qt5版本太旧,现在无法升级,而从Qt5

5.10开始,startDetached还返回pid以及启动过程中的布尔结果。在我的测试中,在开始等待窗口创建的while周期之前,我手动设置了procId(通过静态QInputBox.getInt())。显然,还有其他方法可以执行此操作(并获取窗口的xid)。

import sys

from PyQt5 import QtCore, QtGui, QtWidgets

import gi

gi.require_version('Wnck', '3.0')

from gi.repository import Wnck, Gdk

class Container(QtWidgets.QTabWidget):

def __init__(self):

QtWidgets.QTabWidget.__init__(self)

self.embed('xterm')

def embed(self, command, *args):

proc = QtCore.QProcess()

proc.setProgram(command)

proc.setArguments(args)

started, procId = proc.startDetached()

if not started:

QtWidgets.QMessageBox.critical(self, 'Command "{}" not started!')

return

attempts = 0

while attempts < 10:

screen = Wnck.Screen.get_default()

screen.force_update()

# this is required to ensure that newly mapped window get listed.

while Gdk.events_pending():

Gdk.event_get()

for w in screen.get_windows():

if w.get_pid() == procId:

window = QtGui.QWindow.fromWinId(w.get_xid())

container = QtWidgets.QWidget.createWindowContainer(window, self)

self.addTab(container, command)

return

attempts += 1

QtWidgets.QMessageBox.critical(self, 'Window not found', 'Process started but window not found')

app = QtWidgets.QApplication(sys.argv)

w = Container()

w.show()

sys.exit(app.exec_())

以上是 如何使用PyQT5附加和分离外部应用程序或使外部应用程序停靠? 的全部内容, 来源链接: utcz.com/qa/420700.html

回到顶部