将Python解析器嵌入Qt控件中为用户提供了更直观、交互式的编程体验,同时增加了应用程序的可扩展性和定制性。这对于需要融合图形用户界面和Python脚本的应用程序来说是一种有力的工具。
简单实现效果如下图:
实现原理:
-
运行Python脚本:
- 在
runScript
函数中,连接了两个按钮的点击信号到runScript
和runPyFliesScript
槽函数。 - 当用户点击"Run"或“RunFiles”按钮时,获取用户在QTextEdit中输入的Python脚本或Python解释器路径。
- 使用QProcess创建一个新进程,并通过
startDetached
方法以分离模式运行Python脚本。 - 如果启动失败,输出错误信息;否则,等待进程完成并获取执行结果,显示在QLineEdit中。
- 在
-
处理进程结束信号:
- 当QProcess完成脚本执行时,会触发
onScriptFinished
函数。 - 该函数清除QLineEdit的内容,并通过判断进程的退出状态来处理执行结果。
- 如果进程正常退出,读取标准输出并显示在QLineEdit中,否则输出错误信息。
- 当QProcess完成脚本执行时,会触发
源码如下:
#ifndef PYTHONINTERPRETE_H
#define PYTHONINTERPRETE_H
#include <QWidget>
#include <QWidget>
#include <QLineEdit>
#include <QTextEdit>
#include <QPushButton>
#include <QVBoxLayout>
#include <QProcess>
class PythonInterpreterWidget : public QWidget
{
Q_OBJECT
public:
PythonInterpreterWidget(QWidget *parent = 0);
~PythonInterpreterWidget();
public slots:
// 运行脚本
void runScript();
// 运行python文件脚本
void runPyFliesScript();
//脚本执行完成输出
void onScriptFinished(int exitCode, QProcess::ExitStatus exitStatus);
private:
QLineEdit* _lineEdit = nullptr;
QTextEdit* _textEdit = nullptr;
QPushButton* _runButton = nullptr;
QPushButton* _runPyFliesButton = nullptr;
};
#endif // PYTHONINTERPRETE_H
#include "PythonInterprete.h"
#include <QDebug>
PythonInterpreterWidget::PythonInterpreterWidget(QWidget *parent)
: QWidget(parent)
{
// 设置布局
this->setFixedSize(500,400);
_lineEdit = new QLineEdit(this);
_textEdit = new QTextEdit(this);
_runButton = new QPushButton("Run", this);
_runPyFliesButton = new QPushButton("RunFiles",this);
_lineEdit->setReadOnly(true);
QHBoxLayout* hlay = new QHBoxLayout;
QVBoxLayout* layout = new QVBoxLayout(this);
hlay->addWidget(_runButton);
hlay->addWidget(_runPyFliesButton);
layout->addWidget(_lineEdit);
layout->addWidget(_textEdit);
layout->addLayout(hlay);
setLayout(layout);
// 运行Python脚本
connect(_runButton, &QPushButton::clicked, this, &PythonInterpreterWidget::runScript);
connect(_runPyFliesButton, &QPushButton::clicked, this, &PythonInterpreterWidget::runPyFliesScript);
}
PythonInterpreterWidget::~PythonInterpreterWidget()
{
}
void PythonInterpreterWidget::runScript()
{
// 获取用户输入的Python脚本 和Python解释器路径
QString pythonScript = _textEdit->toPlainText();
QString pythonPath = "Python文件路径";
// 使用 QProcess 运行 Python 脚本
QProcess* process = new QProcess(this);
connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &PythonInterpreterWidget::onScriptFinished);
// 添加错误处理代码
if (!process->startDetached(pythonPath, QStringList() << "-c" << pythonScript))
{
qDebug() << "Error starting the process:" << process->errorString();
}
// 运行脚本
process->start(pythonPath, QStringList() << "-c" << pythonScript);
}
void PythonInterpreterWidget::runPyFliesScript()
{
_lineEdit->clear();
QProcess* process = new QProcess(this);
QString pythonScript = _textEdit->toPlainText();
QString pythonPath = "Python文件路径";
// 执行python文件
QStringList arguments;
arguments << pythonScript;
process->start(pythonPath, arguments);
process->waitForFinished();
// 获取执行结果
QString str = process->readAllStandardOutput();
if (str.isEmpty())
{
qDebug() << "null";
}
_lineEdit->setText(str);
}
void PythonInterpreterWidget::onScriptFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
_lineEdit->clear();
Q_UNUSED(exitCode);
Q_UNUSED(exitStatus);
// 获取发送信号的 QProcess 对象
QProcess* process = qobject_cast<QProcess*>(sender());
if (process)
{
//进程正常退出
if ( QProcess::NormalExit == exitStatus)
{
QString output = process->readAllStandardOutput();
_lineEdit->setText(output);
}
else
{
QString error = process->readAllStandardError();
qDebug() << "Script execution error:" << error;
}
process->deleteLater();
}
}