如何使用嵌入在PyQt GUI中的终端

时间:2015-03-18 00:49:46

标签: python user-interface terminal pyqt

现有的环境和框架可以通过Bash终端使用,我想在其中创建一个GUI。我想到的是以下流程:

  • 在Bash会话中,设置了框架环境。这会导致从会话中设置从环境变量到身份验证的所有内容。
  • 运行Python GUI脚本以包围现有会话并使后续步骤更容易运行。
  • GUI出现,一方面显示嵌入式终端中的Bash会话,另一方面显示一组按钮,这些按钮对应于可在现有框架环境中运行的各种命令。
  • 可以在GUI中按下按钮,从而导致运行某些Bash命令。运行结果显示在嵌入式终端中。

创建这样一个GUI的好方法是什么?我意识到与现有环境交互的想法可能很棘手。如果它特别棘手,我愿意在GUI的一个会话中重新创建环境。在任何情况下,GUI如何与嵌入式终端交互。当按下GUI按钮时,如何在嵌入式终端中运行和显示命令?

GUI的基本启动(具有嵌入式终端)如下:

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class embeddedTerminal(QWidget):

    def __init__(self):

        QWidget.__init__(self)
        self.resize(800, 600)
        self.process  = QProcess(self)
        self.terminal = QWidget(self)
        layout = QVBoxLayout(self)
        layout.addWidget(self.terminal)
        self.process.start(
            'xterm',
            ['-into', str(self.terminal.winId())]
        )

if __name__ == "__main__":
    app = QApplication(sys.argv)
    main = embeddedTerminal()
    main.show()
    sys.exit(app.exec_())

如果按下GUI中的按钮,我怎么能在这个嵌入式终端上运行top

2 个答案:

答案 0 :(得分:5)

如果 是一个真正的终端和一个真正的shell(而不只是接受一行输入,运行一些命令,然后显示输出) - tmux怎么样?

您可以使用类似tee的内容将输出恢复到您的程序中。

请注意,tmux会话可能会在您的程序运行中持续存在,因此您需要了解其工作原理以及如何控制它。

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class embeddedTerminal(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        self._processes = []
        self.resize(800, 600)
        self.terminal = QWidget(self)
        layout = QVBoxLayout(self)
        layout.addWidget(self.terminal)
        self._start_process(
            'xterm',
            ['-into', str(self.terminal.winId()),
             '-e', 'tmux', 'new', '-s', 'my_session']
        )
        button = QPushButton('List files')
        layout.addWidget(button)
        button.clicked.connect(self._list_files)

    def _start_process(self, prog, args):
        child = QProcess()
        self._processes.append(child)
        child.start(prog, args)

    def _list_files(self):
        self._start_process(
            'tmux', ['send-keys', '-t', 'my_session:0', 'ls', 'Enter'])

if __name__ == "__main__":
    app = QApplication(sys.argv)
    main = embeddedTerminal()
    main.show()
    sys.exit(app.exec_())

此处更多:https://superuser.com/questions/492266/run-or-send-a-command-to-a-tmux-pane-in-a-running-tmux-session

答案 1 :(得分:0)

如果有人遇到此问题,则对其进行一些修改以关闭tmux会话(如果存在),因为上一个会话没有在退出时关闭它。还要将其设置为PySide2

现在唯一需要的是调整大小。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import psutil
import os
import platform
import sys
from pathlib import Path
from subprocess import call

from PySide2 import QtCore
from PySide2.QtCore import *
from PySide2.QtWidgets import QWidget, QVBoxLayout, QPushButton, QApplication

platform = platform.system()
print(str(platform))

term_dir = Path(os.path.abspath(os.path.dirname(__file__))) / 'terminus'

if platform == 'Windows':
    term_bin = str(term_dir) + '/' + str(platform.lower()) + '/' + 'terminus.exe'

elif platform == 'Linux':
    term_bin = str(term_dir) + '/' + str(platform.lower()) + '/' + 'terminus'

print(term_bin)


class embeddedTerminal(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        self._processes = []
        self.resize(800, 600)
        self.terminal = QWidget(self)
        layout = QVBoxLayout(self)
        layout.addWidget(self.terminal)
        self._stop_process()
        self._start_process(
            'xterm',
            ['-into', str(self.terminal.winId()),
             '-e', 'tmux', 'new', '-s', 'my_session']
        )
        button = QPushButton('List files')
        layout.addWidget(button)
        button.clicked.connect(self._list_files)

    def _start_process(self, prog, args):
        child = QProcess()
        self._processes.append(child)
        child.start(prog, args)

    def _list_files(self):
        self._start_process(
            'tmux', ['send-keys', '-t', 'my_session:0', 'ls', 'Enter'])

    @classmethod
    def _stop_process(self):
        call(["tmux", "kill-session", "-t", "my_session"])


if __name__ == "__main__":
    app = QApplication(sys.argv)
    main = embeddedTerminal()
    main.show()
    sys.exit(app.exec_())