当前位置: 首页 > 面试题库 >

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

阎知
2023-03-14
问题内容

我正在使用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 / init
.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_())


 类似资料:
  • 问题内容: 我正在制作一个简单的闹钟应用程序,通知用户。我想制作一个警报框,使用户可以选择在警报关闭时将其关闭。我能够制作警报框,但它仅出现在应用程序中,而不出现在应用程序之外。我了解该应用必须在后台运行。如果我需要显示更多代码或更具体,请问一下。 问题答案: 将行添加为: 现在检查。

  • 我需要帮助在外部服务器上运行/调试我的GWT应用程序,而不是使用默认的jetty服务器。我读了几个与这个问题相关的主题,例如。 > 在哪里编写gwt-noserver选项以避免jetty? 如何使用GWT和(常规servlet)Jetty后端设置eclipse http://www.gwtproject.org/doc/latest/devguideCompilinganddebugging.ht

  • 我在谷歌播放器上看到一些应用程序,可以让你为Android5.0版录制整个屏幕。我已经深入Android参考了一段时间,但找不到正确的方法。有人能给我一个小提示吗? 另外,我知道Android系统不会给你全屏缓冲区访问的版本

  • 问题内容: 我正在编写一个使用node.js访问本地文件系统的桌面Web应用程序。我目前可以使用node.js打开文件并将其复制到硬盘驱动器上的不同位置。我还想做的是允许用户使用与文件类型关联的应用程序打开特定文件。换句话说,如果用户在Windows环境中选择“ myfile.doc”,它将使用该文件启动MSWord。 我一定是术语的受害者,因为除了与node.js进行通信的子进程的生成之外,我什

  • 我正在开发一个spring boot应用程序 我想用外部文件(例如)重写中的某些属性。 我尝试了几种方法: 中的“我的应用程序.属性”中的 我使用对其进行了测试。第一个方法只添加了属性,但没有重写它们。