gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 18:36:29 27 4
gpt4 key购买 nike

我正在使用 ROS 为多机器人系统开发 GUI,但我在界面中最不想做的事情是卡住:在我的应用程序中嵌入 RVIZ、GMAPPING 或其他屏幕。我已经在界面中放置了一个终端,但我无法解决如何将外部应用程序窗口添加到我的应用程序。我知道 PyQt5 有 createWindowContainer,它使用窗口 ID 来停靠外部应用程序,但我没有找到任何示例来帮助我。

如果可能的话,我想在我的应用程序的选项卡式框架内拖放一个外部窗口。但是,如果这是不可能的或太难了,我很高兴只在单击按钮后打开选项卡式框架内的窗口。

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

已经尝试翻译attaching/detaching code使用 wmctrl 命令将代码写入 linux,但没有工作。见 my code here .

也已经尝试过rviz Python Tutorial但我收到了错误:

回溯(最近一次通话最后):
文件“rvizTutorial.py”,第 23 行,在
导入rviz
文件“/opt/ros/indigo/lib/python2.7/dist-packages/rviz/ init .py”,第 19 行,在
导入 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 以及启动过程的 bool 结果。
在我的测试中,我在开始等待创建窗口的 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_())

关于python - 如何使用 PyQT5 附加和分离外部应用程序或停靠外部应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57015932/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com