如何使用嵌入在 PyQt GUI 中的终端
how to use a terminal embedded in a PyQt GUI
有一个现有的环境和框架可以通过 Bash 终端使用,我想围绕它制作一个 GUI。我想到的是以下流程:
- 在一个Bash会话中,搭建了框架环境。这导致在会话中设置从环境变量到身份验证的所有内容。
- Python GUI 脚本是 运行 以环绕现有会话并使 运行 后续步骤更容易。
- GUI 出现,一侧显示嵌入式终端中的 Bash 会话,另一侧显示一组按钮,对应于现有框架环境中可以 运行 的各种命令.
- 可以在 GUI 中按下按钮,导致某些 Bash 命令成为 运行。 运行 的结果显示在嵌入式终端中。
创建此类 GUI 的好方法是什么?我意识到与 existing 环境交互的想法可能很棘手。如果它特别棘手,我愿意在 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
?
如果它必须是一个真正的终端和一个真正的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_())
如果其他人遇到此问题,请对其进行一些轻微修改以关闭 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_())
有一个现有的环境和框架可以通过 Bash 终端使用,我想围绕它制作一个 GUI。我想到的是以下流程:
- 在一个Bash会话中,搭建了框架环境。这导致在会话中设置从环境变量到身份验证的所有内容。
- Python GUI 脚本是 运行 以环绕现有会话并使 运行 后续步骤更容易。
- GUI 出现,一侧显示嵌入式终端中的 Bash 会话,另一侧显示一组按钮,对应于现有框架环境中可以 运行 的各种命令.
- 可以在 GUI 中按下按钮,导致某些 Bash 命令成为 运行。 运行 的结果显示在嵌入式终端中。
创建此类 GUI 的好方法是什么?我意识到与 existing 环境交互的想法可能很棘手。如果它特别棘手,我愿意在 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
?
如果它必须是一个真正的终端和一个真正的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_())
如果其他人遇到此问题,请对其进行一些轻微修改以关闭 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_())