You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt5中点击AI按钮如何将外部Python脚本输出设置到LineEdit

问题描述

我开发了一个基于AI的PyQt5程序,已查阅StackOverflow上所有关于PyQt设置文本的帖子,希望点击Auto(AI)按钮时,将字符串设置到lineEdit控件中。

当前按钮点击事件代码如下:

def AI_click(self):
        #self.lineEdit.setText("YO")
        os.system('python detect_video.py --weights ./checkpoints/custom-416 --size 416 --model yolov4 --video 0 --plate')
        #self.lineEdit.setText(line1)

本质上,AI按钮会执行Python脚本并输出字符串,我想知道如何在GUI文件中获取另一个.py文件的输出字符串。目前程序执行脚本后,无法执行self.lineEdit.setText(line1)来设置文本,也无法获取该字符串。完整代码如下:

class Ui_Dialog(object):
def setupUi(self, Dialog,var):
    Dialog.setObjectName("Dialog")
    Dialog.resize(1120, 850)
    Dialog.setStyleSheet("QDialog#Dialog{\n""background-color: 
    qlineargradient(spread:pad,x1:0.0113636, y1:0.966, x2:1, y2:0, 
    stop:0 rgba(0, 0, 0, 255), stop:1 rgba(255, 255, 255, 255))\n"
    "\n"
    "}\n"
    "\n"
    "")
    self.widget = QtWidgets.QWidget(Dialog)
    self.widget.setGeometry(QtCore.QRect(0, 0, 201, 851))
    self.widget.setStyleSheet("\n"
    "background-color: rgb(100, 100, 100);")
    self.widget.setObjectName("widget")
    self.dashboardButton = QtWidgets.QPushButton(self.widget)
    self.dashboardButton.setGeometry(QtCore.QRect(0, 250, 201, 51))
    self.dashboardButton.setStyleSheet("QPushButton {\n"
    "    background-color: rgb(255, 255, 255);\n"
    "    color: #FFFFFF;\n"
    "    \n"
    "    padding: 2px;\n"
    "    font: bold 20px; color:black;\n"
    "    \n"
    "    \n"
    "   }\n"
    "QPushButton:hover {\n"
    "    background-color: rgb(98, 98, 98);\n"
    "}")
    self.dashboardButton.setObjectName("dashboardButton")
    self.dashboardButton_2 = QtWidgets.QPushButton(self.widget)
    self.dashboardButton_2.setGeometry(QtCore.QRect(0, 370, 201, 51))
    self.dashboardButton_2.setStyleSheet("QPushButton {\n"
    "    background-color: rgb(255, 255, 255);\n"
    "    color: #FFFFFF;\n"
    "    \n"
    "    padding: 2px;\n"
    "    font: bold 20px; color:black;\n"
    "    \n"
    "    \n"
    "   }\n"
    "QPushButton:hover {\n"
    "    background-color: rgb(98, 98, 98);\n"
    "}")
    self.dashboardButton_2.setObjectName("dashboardButton_2")
    self.label = QtWidgets.QLabel(Dialog)
    self.label.setGeometry(QtCore.QRect(250, 20, 171, 91))
    self.label.setStyleSheet("font-size: 30px;\n"
    "font: bold;\n"
    "")
    self.label.setObjectName("label")
    self.label_2 = QtWidgets.QLabel(Dialog)
    self.label_2.setGeometry(QtCore.QRect(630, 70, 416, 416))
    self.label_2.setText("")
    self.label_2.setPixmap(QtGui.QPixmap("D:/Downloads/numplate.jpg"))
    self.label_2.setScaledContents(True)
    self.label_2.setObjectName("label_2")
    self.label_3 = QtWidgets.QLabel(Dialog)
    self.label_3.setGeometry(QtCore.QRect(640, 530, 401, 241))
    self.label_3.setText("")
    self.label_3.setPixmap(QtGui.QPixmap("D:/Downloads/20886263.jpg"))
    self.label_3.setScaledContents(True)
    self.label_3.setObjectName("label_3")
    self.lineEdit = QtWidgets.QLineEdit(Dialog)
    #self.lineEdit.setText("YO")
    # if string!=None:
    #         print("called")
    #         print(string)
    #         self.lineEdit.setText(string)
    self.lineEdit.setGeometry(QtCore.QRect(300, 280, 221, 41))
    self.lineEdit.setObjectName("lineEdit")
    
    self.lineEdit_2 = QtWidgets.QLineEdit(Dialog)
    self.lineEdit_2.setGeometry(QtCore.QRect(300, 360, 221, 41))
    self.lineEdit_2.setObjectName("lineEdit_2")
    self.label_4 = QtWidgets.QLabel(Dialog)
    self.label_4.setGeometry(QtCore.QRect(300, 260, 81, 16))
    self.label_4.setObjectName("label_4")
    self.label_5 = QtWidgets.QLabel(Dialog)
    self.label_5.setGeometry(QtCore.QRect(300, 340, 81, 16))
    self.label_5.setObjectName("label_5")
    self.pushButton = QtWidgets.QPushButton(Dialog)
    self.pushButton.setGeometry(QtCore.QRect(420, 430, 101, 31))
    self.pushButton.setObjectName("pushButton")
    self.pushButton_AI = QtWidgets.QPushButton(Dialog)
    self.pushButton_AI.setGeometry(QtCore.QRect(300, 430, 101, 31))
    self.pushButton_AI.setObjectName("pushButton_AI")

    print("car:"+var)
    self.pushButton.clicked.connect(self.clickme)
    self.pushButton_AI.clicked.connect(self.AI_click)
    lineEdit= self.lineEdit
    self.retranslateUi(Dialog)
    QtCore.QMetaObject.connectSlotsByName(Dialog)
def AI_click(self):
        #self.lineEdit.setText("YO")
        os.system('python detect_video.py --weights ./checkpoints/custom-416 --size 416 --model yolov4 --video 0 --plate')
        #self.lineEdit.setText(line1)


def clickme(self):
    np=self.lineEdit.text()
    cnic=self.lineEdit_2.text()
    table_data(np,cnic)
    
    # printing pressed
    print(np+cnic)
def retranslateUi(self, Dialog):
    _translate = QtCore.QCoreApplication.translate
    Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
    self.dashboardButton.setText(_translate("Dialog", "Dashboard"))
    self.dashboardButton_2.setText(_translate("Dialog", "Record"))
    self.label.setText(_translate("Dialog", "Dashboard"))
    self.label_4.setText(_translate("Dialog", "Number Plate:"))
    self.label_5.setText(_translate("Dialog", "CNIC:"))
    self.pushButton.setText(_translate("Dialog", "Save "))
    self.pushButton_AI.setText(_translate("Dialog", "Auto"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
var=""
ui.setupUi(Dialog,var)
Dialog.show()
sys.exit(app.exec_())
解决方案

os.system仅能返回脚本执行的状态码,无法捕获输出内容。要实现需求,需用subprocess模块获取脚本输出,同时为避免阻塞GUI主线程,推荐结合子线程执行。

方法一:同步捕获输出(简单场景)

修改AI_click方法,使用subprocess.check_output捕获脚本标准输出:

import subprocess

def AI_click(self):
    try:
        # 执行脚本并捕获输出,指定encoding将字节串转为字符串
        output = subprocess.check_output(
            ["python", "detect_video.py", "--weights", "./checkpoints/custom-416", "--size", "416", "--model", "yolov4", "--video", "0", "--plate"],
            stderr=subprocess.STDOUT,  # 同时捕获错误输出
            encoding="utf-8"
        )
        # 根据脚本输出格式提取目标字符串,这里假设输出是单行结果
        target_str = output.strip()
        self.lineEdit.setText(target_str)
    except subprocess.CalledProcessError as e:
        # 脚本执行出错时显示错误信息
        self.lineEdit.setText(f"执行失败: {e.output}")

方法二:子线程执行(推荐,避免GUI卡顿)

如果detect_video.py运行耗时较长,直接在主线程执行会导致界面冻结,需要用QThread异步执行:

  1. 定义子线程类:
from PyQt5.QtCore import QThread, pyqtSignal
import subprocess

class ScriptWorker(QThread):
    # 定义信号,传递输出结果和错误信息
    output_ready = pyqtSignal(str)
    error_occurred = pyqtSignal(str)

    def run(self):
        try:
            result = subprocess.check_output(
                ["python", "detect_video.py", "--weights", "./checkpoints/custom-416", "--size", "416", "--model", "yolov4", "--video", "0", "--plate"],
                stderr=subprocess.STDOUT,
                encoding="utf-8"
            )
            self.output_ready.emit(result.strip())
        except subprocess.CalledProcessError as e:
            self.error_occurred.emit(f"执行错误: {e.output}")
  1. 修改AI_click方法及添加槽函数:
def AI_click(self):
    # 创建线程实例
    self.worker = ScriptWorker()
    # 连接信号到处理函数
    self.worker.output_ready.connect(self.update_lineedit)
    self.worker.error_occurred.connect(self.show_error)
    # 启动线程
    self.worker.start()

def update_lineedit(self, text):
    # 更新lineEdit内容
    self.lineEdit.setText(text)

def show_error(self, error_msg):
    # 显示错误信息
    self.lineEdit.setText(error_msg)

关键注意点

  • 确保detect_video.py确实将需要的字符串输出到标准输出(而非仅打印到控制台或写入文件)。
  • 如果脚本输出多行内容,需要根据实际格式提取目标字符串(比如提取车牌号那一行)。
  • 使用子线程时,注意避免重复创建线程,可在启动前判断线程状态。

内容的提问来源于stack exchange,提问作者Python_bot_here

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 13:18:27