使用 Python 脚本自动化 Delphi 2007 应用程序 - 如何明确地引用控件?

问题描述 投票:0回答:1

我有一个遗留的 Delphi 应用程序,我需要对其进行自动化以进行测试。我很难将自动化请求定向到正确的组件。包含的示例演示了该问题(无论如何在我的环境中)。这是我想要控制的一个简单的 Delphi 应用程序:

项目1.dpr

program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

Unit1.pas

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    CheckBox1: TCheckBox;
    Timer1: TTimer;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Button5: TButton;
    Label2: TLabel;
    Panel1: TPanel;
    procedure ControlClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ControlClick(Sender: TObject);
begin
Memo1.Lines.Add (Format ('Control "%s" clicked', [TControl (Sender).Name])) ;
end;


procedure TForm1.Timer1Timer(Sender: TObject);
begin
if Assigned(Screen.ActiveControl) then
    begin
    Panel1.Caption := Screen.ActiveControl.Name ;
    end
else
    begin
    Panel1.Caption := 'None.' ;
    end ;
end ;

end.

Unit1.dfm

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 212
  ClientWidth = 407
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Label2: TLabel
    Left = 73
    Top = 193
    Width = 32
    Height = 13
    Caption = 'Focus:'
  end
  object Memo1: TMemo
    Left = 24
    Top = 8
    Width = 201
    Height = 177
    TabOrder = 0
  end
  object Button1: TButton
    Left = 304
    Top = 11
    Width = 75
    Height = 25
    Caption = '1'
    TabOrder = 1
    OnClick = ControlClick
  end
  object CheckBox1: TCheckBox
    Left = 296
    Top = 171
    Width = 97
    Height = 17
    Caption = 'CheckBox1'
    TabOrder = 6
    OnClick = ControlClick
  end
  object Button2: TButton
    Left = 304
    Top = 42
    Width = 75
    Height = 25
    Caption = '2'
    TabOrder = 2
    OnClick = ControlClick
  end
  object Button3: TButton
    Left = 304
    Top = 73
    Width = 75
    Height = 25
    Caption = '3'
    TabOrder = 3
    OnClick = ControlClick
  end
  object Button4: TButton
    Left = 304
    Top = 104
    Width = 75
    Height = 25
    Caption = '4'
    TabOrder = 4
    OnClick = ControlClick
  end
  object Button5: TButton
    Left = 304
    Top = 135
    Width = 75
    Height = 25
    Caption = '5'
    TabOrder = 5
    OnClick = ControlClick
  end
  object Panel1: TPanel
    Left = 116
    Top = 191
    Width = 109
    Height = 17
    TabOrder = 7
  end
  object Timer1: TTimer
    Interval = 300
    OnTimer = Timer1Timer
    Left = 240
    Top = 152
  end
end

自动化.py

import pywinauto
from pywinauto import application

def Click (AForm, AControlName):
    FControl = AForm [AControlName]
    FControl.click()
    return ()

FormTitle = "Form1"
try:
    app = application.Application().connect(title=FormTitle)
    form1 = app[FormTitle]

    Click (form1, "Button1")
    Click (form1, "Button2")
    Click (form1, "Button3")
    Click (form1, "Button4")
    Click (form1, "Button5")

    Click (form1, "Checkbox1")

    exit (0)

except pywinauto.application.ProcessNotFoundError:
    print(f"No running instance of {FormTitle} found.")
    exit (1)

except Exception as e:
    print(f"An error occurred: {str(e)}")
    exit (1)

一切都很好,只是按钮颠倒了。如果我直接点击 Button1,Button5 就会记录一次点击。其他实验表明,不一定可以预测如何重定向请求 - 例如,复选框就可以,尽管我从未尝试过更多数量的复选框。我想要的只是一种引用控件的明确方式 - 因为控件名称并不能解决问题。

更新 进一步的实验似乎表明控件的 caption 是我需要传递给调用以向控件发送点击消息的内容。

python delphi ui-automation pywinauto delphi-2007
1个回答
0
投票

按属性或按项目访问执行防错字搜索过程。此过程中的索引是不同的。 入门指南中有更详细的描述。

要按精确标题搜索,您需要以这种方式制定搜索条件(它工作得更快!):

form1.child_window(title="1", class_name="TButton").click()
form1.child_window(title="2", class_name="TButton").click()    
form1.child_window(title="3", class_name="TButton").click()

如果你想知道正确的规格,就转储它吧:

form1.dump_tree()

因此您可以从该转储中复制粘贴此类

child_window
规格。

顺便说一句,

connect
方法有一个已知问题,目前需要显式超时:
connect(title=FormTitle, timeout=10)

© www.soinside.com 2019 - 2024. All rights reserved.