【问题标题】:Execute command to a Python script from separate Python script?从单独的 Python 脚本执行命令到 Python 脚本?
【发布时间】:2020-10-24 15:59:33
【问题描述】:

我正在尝试将命令从一个 python 脚本发送到另一个在终端中运行的脚本。

我正在运行 Raspbian 的 RPi 上运行两个 python 脚本。第一个脚本是一个循环,等待用户输入一个数字并将其添加到总数中。第二个脚本使用 PySide2 在释放 QPushButton 时打印一个数字。

如何使 QPushButton 释放时运行的函数向等待的第一个脚本发送命令(或变量)并执行它?

我已经阅读了一些关于使用 subprocess.callos.system 的内容,但我不确定我在用这些命令做什么,或者它们是否适合我想做的事情。

第一个脚本:

x = 0
while x < 10:
    y = int(input("enter number:"))
    x += y
    print(x)

print("x is ten!")

第二个脚本:

import sys
from PySide2.QtWidgets import *

class MainWindow(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        self.btn = QPushButton("test")

        layout = QVBoxLayout()
        layout.addWidget(self.btn)

        self.setLayout(layout)

        self.btn.released.connect(self.btnpress)

    def btnpress(self):
        print(1)

app = QApplication(sys.argv)

window = MainWindow()
window.show()
app.exec_()

【问题讨论】:

  • 因为这两个脚本都在python中,你能不能只用import第一个脚本中的第二个脚本而不是使用subprocess.callos.system
  • 如果我这样做,我必须等待第一个脚本完成运行,然后再启动第二个脚本并等待按钮出现。
  • @Welshhobo 我不明白你为什么删除了你以前的帖子,因为我正在研究一个答案,它实现了使用 dbus 和 Qt 的事件循环的使用,恕我直言在这方面更优雅但无论如何都很好案例我已经根据您提供的内容提出了解决方案:使用 QProcess 。
  • @eyllanesc 啊抱歉,我认为脚本依赖于需要先安装的一堆模块,所以我认为它会更简单,我会在发布一个更简单的示例时得到更多答案。如果您仍然拥有它,那将非常方便。

标签: python python-3.x subprocess pyside2


【解决方案1】:

如果您想运行脚本并通过标准输入发送信息,那么在 Qt 中最好的选择是使用 QProcess:

import os.path
import sys

from PySide2.QtCore import QProcess
from PySide2.QtWidgets import QApplication, QPushButton, QSpinBox, QVBoxLayout, QWidget

CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))


class MainWindow(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        self.btn = QPushButton("test")
        self.spinbox = QSpinBox()

        self.process = QProcess()
        self.process.readyReadStandardError.connect(self.handle_readyReadStandardError)
        self.process.readyReadStandardOutput.connect(
            self.handle_readyReadStandardOutput
        )
        self.process.setProgram(sys.executable)
        script_path = os.path.join(CURRENT_DIR, "script.py")
        self.process.setArguments([script_path])
        self.process.start()

        layout = QVBoxLayout(self)
        layout.addWidget(self.spinbox)
        layout.addWidget(self.btn)
        self.btn.released.connect(self.btnpress)

    def btnpress(self):
        number = self.spinbox.value()

        msg = "{}\n".format(number)
        self.process.write(msg.encode())

    def handle_readyReadStandardError(self):
        print(self.process.readAllStandardError().data().decode())

    def handle_readyReadStandardOutput(self):
        print(self.process.readAllStandardOutput().data().decode())


app = QApplication(sys.argv)

window = MainWindow()
window.show()
app.exec_()

注意:您不必在第二个 shell 中运行脚本,因为脚本本身会启动它。

【讨论】:

  • 效果很好,将尝试在我的主程序中实现它,看看它是如何进行的。谢谢!
  • 感谢您的帮助,这是一个巨大的帮助。如前所述,我试图让它与使用 dbus 的蓝牙控制器一起工作。我无法让它读取脚本的print 输出。我做了一些阅读,发现 readAllStandardOutput 方法存储到 QByteArray 中。我正在阅读有关此的文档,但我无法理解它是如何工作的。 AFAIK 这不像常规列表/数组那样工作吗?即我不能只是 print 循环中的每个“单元格”来模拟输出。用我的实际程序的简化版本写一个新问题值得吗?
【解决方案2】:

当存在明确的父/子关系时,子流程才有意义。这听起来更像是您有两个独立的代理,它们偶尔需要通信。根据您的需要,有各种进程间通信 (IPC) 机制,最基本的是信号,其中任何一个进程都可以向另一个进程发送一点信息以通知它发生了某些事件。对于更复杂的需求,设置共享内存,或通过套接字或 FIFO 进行通信。

【讨论】:

    【解决方案3】:

    我认为您必须添加第三方,例如:

    1. 数据库
    2. REDIS
    3. 文件

    但您不能不将命令从正在运行的脚本发送到另一个正在运行的脚本, 因为 CLI 脚本仅在他的 shell 中等待命令。 问候

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-15
      • 2018-02-27
      • 1970-01-01
      • 1970-01-01
      • 2016-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多