python4delphi 的使用方法简介

Python4Delphi (P4D) 是一组免费的 Delphi 组件,它允许你:
  • 在 Delphi 应用中嵌入 Python 解释器
  • 在 Python 中使用 Delphi 的类和对象
  • 双向调用:Delphi ↔ Python
核心组件:
  • TPythonEngine - Python 解释器引擎
  • TPythonModule - 创建 Python 模块
  • TPythonType - 定义 Python 类型
  • TPythonDelphiVar - Delphi 变量与 Python 共享
第二步:基础 Demo - 最简单的 "Hello World"

2.1 界面准备

在 Delphi 中新建 VCL 应用,放置以下组件:
  1. TPythonEngine (来自 Python4Delphi 组件面板)
  2. TMemo (显示输出,命名为 MemoOutput)
  3. TButton (执行按钮)
 
uses
  PythonEngine;procedure TForm1.Button1Click(Sender: TObject);begin
  // 【第1段】初始化 Python 引擎
  PythonEngine1.LoadDll;  // 加载 python.dll
  
  // 【第2段】执行 Python 代码
  PythonEngine1.ExecString('print("Hello from Python!")');  
  // 【第3段】获取 Python 版本信息
  MemoOutput.Lines.Add(PythonEngine1.EvalString('import sys; sys.version'));end;

| 代码段 |   作用                    |                           关键点                      |
| ------- | ------------------- | --------------------------------------- |
| 第1段  | 加载 Python DLL   | 必须先执行,否则引擎未就绪              |
| 第2段  | 执行 Python 语句  | `ExecString` 用于执行不返回值的代码  |
| 第3段  | 获取 Python 信息  | `EvalString` 用于获取表达式返回值      |

Delphi 向 Python 传递变量

procedure TForm1.PassValuesToPython;var
  PyValue: PPyObject;  // Python 对象指针begin
  PythonEngine1.LoadDll;  
  // 【第1段】创建 Python 整数
  PyValue := PythonEngine1.PyLong_FromLong(42);  
  // 【第2段】将变量注入 Python 全局命名空间  PythonEngine1.PyDict_SetItemString(
    PythonEngine1.GetMainModule.__dict__, 
    'delphi_number', 
    PyValue
  );  
  // 【第3段】在 Python 中使用这个变量
  PythonEngine1.ExecString('print(f"Delphi传来的数字: {delphi_number}")');  
  // 【第4段】释放 Python 对象(重要!防止内存泄漏)  PythonEngine1.Py_DecRef(PyValue);end;

关键概念解释:
  • PPyObject - Python 对象的 C 指针,所有 Python 数据都是这种类型
  • PyLong_FromLong() - 将 Delphi 整数转为 Python 整数
  • GetMainModule.__dict__ - Python 的全局变量字典
  • Py_DecRef() - 必须调用,减少引用计数,否则内存泄漏

使用 TPythonDelphiVar 组件

这是更简单的数据交换方式,不需要手动管理引用计数。

界面设置

  //添加 TPythonDelphiVar 组件,设置 VarName = "delphi_var"
procedure TForm1.UseDelphiVar;
begin
  PythonEngine1.LoadDll;
  
  // 【第1段】通过组件赋值(自动处理类型转换)
  PythonDelphiVar1.Value := '来自 Delphi 的字符串';
  
  // 【第2段】Python 中直接使用这个变量名
  PythonEngine1.ExecString('print(delphi_var.upper())');
  
  // 【第3段】Python 修改后,Delphi 读取
  PythonEngine1.ExecString('delphi_var = "被 Python 修改了"');
  ShowMessage(PythonDelphiVar1.Value);  // 显示修改后的值
end;

优势:
  • ✅ 自动内存管理
  • ✅ 自动类型转换(字符串、整数、浮点数、布尔值)
  • ✅ 双向实时同步


创建 Python 可调用的 Delphi 函数

这是 P4D 最强大的功能 - 让 Python 调用你的 Delphi 代码。

复制代码
 AddNumbers(Self, Args: PPyObject): PPyObject; 
   GetPythonEngine 
  
    
     PyArg_ParseTuple(Args, , @A, @B) <>  
    
      
      Result := PyLong_FromLong(A +
    = ;  
  ;
复制代码
复制代码
//注册函数到 Pythonprocedure TForm1.RegisterDelphiFunction;begin
  PythonEngine1.LoadDll;  
  // 【第2段】创建 Python 模块
  with PythonModule1 do  // TPythonModule 组件
  begin
    ModuleName := 'delphi_utils';  // Python 中 import 的名字
    
    // 添加方法: 方法名, 函数指针, 文档字符串
    AddMethod('add', @AddNumbers, 'Add two integers: add(a, b) -> int');    
    // 【第3段】必须调用,实际注册到 Python    Initialize;  end;  
  // 【第4段】Python 中调用 Delphi 函数  PythonEngine1.ExecString(    'import delphi_utils' + sLineBreak +    'result = delphi_utils.add(10, 20)' + sLineBreak +    'print(f"10 + 20 = {result}")'
  );end;
复制代码
PyArg_ParseTuple解析 Python 参数,`'ii'` 表示两个整数     
cdecl必须指定,匹配 Python C API 调用约定  
ModuleNamePython 中 `import` 使用的模块名   
AddMethod将 Delphi 函数暴露给 Python 

 5.学习使用处理Python对象和列表

复制代码
//操作 Python 列表procedure TForm1.WorkWithPythonList;var
  PyList, PyItem: PPyObject;
  I: Integer;begin
  PythonEngine1.LoadDll;  
  // 【第1段】创建 Python 列表
  PyList := PythonEngine1.PyList_New(0);  // 空列表
  
  // 【第2段】向列表添加元素
  for I := 1 to 5 do
  begin
    PyItem := PythonEngine1.PyLong_FromLong(I * 10);
    PythonEngine1.PyList_Append(PyList, PyItem);
    PythonEngine1.Py_DecRef(PyItem);  // 列表已引用,可以释放临时引用
  end;  
  // 【第3段】将列表注入 Python  PythonEngine1.PyDict_SetItemString(
    PythonEngine1.GetMainModule.__dict__,    'my_list',
    PyList
  );
  PythonEngine1.Py_DecRef(PyList);  
  // 【第4段】Python 中使用列表  PythonEngine1.ExecString(    'print(f"列表: {my_list}")' + sLineBreak +    'print(f"总和: {sum(my_list)}")'
  );end;
复制代码




网友留言(0 条)

发表评论