鱼C论坛

 找回密码
 立即注册
查看: 29|回复: 4

请教 我unit1的edit.text可以传给另一个窗口unot2 为什么2不能反传1窗口?

[复制链接]
发表于 昨天 21:11 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
unit Unit2;

{$mode ObjFPC}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs,StdCtrls,Unit1       ;////  <----------这里unit1报错 unit2.pas(8,71) Error: Circular unit reference between Unit2 and Unit1

type

  { TForm2 }

  TForm2 = class(TForm)
    Button1: TButton;
    F2Edit1: TEdit;
    f2Edit2: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private

  public

  end;

var
  Form2: TForm2;

implementation

{$R *.lfm}

{ TForm2 }

procedure TForm2.FormCreate(Sender: TObject);
begin

end;

procedure TForm2.Button1Click(Sender: TObject);
begin
//  F2Edit1.Text:=form1.Edit4.Text;
//  F2Edit2.Text:=form1.edit5.Text;
end;

end.



//ide  lazarus  但是我窗口1的text是可以传给窗口2edit.text 窗口二就不能写传窗口1了  - -!  大哥些 求解
                                                     
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 昨天 21:12 | 显示全部楼层
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtDlgs,
  ExtCtrls, Grids, ComCtrls,Unit2, Menus;  //《-------------------窗口1的这里就不会报错

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    Edit5: TEdit;
    Image1: TImage;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    ListView1: TListView;
    MenuItem1: TMenuItem;
    PopupMenu1: TPopupMenu;
    SaveDialog1: TSaveDialog;
    Timer1: TTimer;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure DrawGrid1Click(Sender: TObject);
    procedure Edit1Change(Sender: TObject);
    procedure Edit3Change(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Image1Click(Sender: TObject);
    procedure Label3Click(Sender: TObject);
    procedure MenuItem1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private

  public


  end;

var
  Form1: TForm1;

  st:string;
      f1_edit:string;
  f2_edit:string;
  a:boolean=true ;
  b:integer=0;

implementation

type
  rec =record
  name:string;
  sex:string;
  age:integer;
  end;

{$R *.lfm}

{ TForm1 }
procedure f( str1:string ; str2:string);
begin
    // TForm1.edit3.Text:=  inttostr( strtoint(str1)+strtoint(str2)) ;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  t1:string;
  t2:string;
  a:real;
  b:real ;
  c:real ;
begin
     t1:=edit1.Text;
     t2:=edit2.Text;
     a:=strtofloat(t1);
     b:=strtofloat(t2);
     c:=a+b;
     edit3.Text:=floattostr(c);

end;

procedure TForm1.Button2Click(Sender: TObject);
var
    tf:textfile;
  a:integer=911;
begin
     if savedialog1.Execute then
     begin
       assignfile(tf,savedialog1.FileName);
       rewrite(tf);
       write(tf,a);
       closefile(tf);
     end;

end;

procedure TForm1.Button3Click(Sender: TObject);
var
  str1:string='tttttt';
begin
     timer1.Interval:=5000;
    showmessage(str1);
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  f1_edit:=edit4.Text;
  f2_edit:=edit5.Text;
  //form1.Hide;
  form2.f2Edit1.Text:=f1_edit;
  form2.f2Edit2.Text:=f2_edit;
end;



procedure TForm1.DrawGrid1Click(Sender: TObject);
begin

end;

procedure TForm1.Edit1Change(Sender: TObject);
begin

end;

procedure TForm1.Edit3Change(Sender: TObject);
begin

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
        close;

end;

procedure TForm1.Image1Click(Sender: TObject);
begin

end;

procedure TForm1.Label3Click(Sender: TObject);
begin

end;

procedure TForm1.MenuItem1Click(Sender: TObject);
begin

end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  b:integer=254 ;
begin
  // if a=true then
  // image1.Top:=image1.Top+30
  // else
  // image1.Top:=image1.Top-30;
   while b>0 do
   begin
       image1.Top:=image1.Top-1  ;
       b:=b-1;
   end;
   //a:=not a;
end;

end.
  //这是窗口1代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 21:12 | 显示全部楼层
鱼油你好!

你的问题是关于两个窗口之间数据双向传递的。从代码看,Unit2 已经 uses 了 Unit1,所以从 Unit1 传数据到 Unit2 是可行的。但反过来不行,主要是因为 Unit2 没有获得 Unit1 窗口实例的引用。

简单来说:你知道 Unit1 长什么样(因为有 uses),但不知道具体要操作哪一个 Unit1。

以下是解决方案:

核心思路:
在 Unit1 中创建/显示 Unit2 时,将 Unit1 自己的引用(例如 Self)传递给 Unit2。

操作步骤:

1.  在 Unit2 中,定义一个变量来保存对 Unit1 实例的引用。
2.  在 Unit1 中,创建 Unit2 时,将自己的引用赋给 Unit2 的这个变量。
3.  在 Unit2 中,就可以通过这个变量来修改 Unit1 的控件了。

示例代码:

在 Unit2 中:

  1. unit Unit2;

  2. interface

  3. uses
  4.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Unit1;

  5. type
  6.   TForm2 = class(TForm)
  7.     Edit2: TEdit;
  8.     Button1: TButton;
  9.     procedure Button1Click(Sender: TObject);
  10.   private
  11.     // 定义一个变量,用于保存 Unit1 的窗口实例
  12.     FMyForm1: TForm1;
  13.   public
  14.     // 一个公共属性或方法,用于接收来自 Unit1 的引用
  15.     property MyForm1: TForm1 write FMyForm1;
  16.   end;

  17. implementation

  18. procedure TForm2.Button1Click(Sender: TObject);
  19. begin
  20.   // 当点击 Unit2 的按钮时,将 Edit2 的文本传回给 Unit1 的 Edit1
  21.   if Assigned(FMyForm1) then // 先检查引用是否存在,避免出错
  22.     FMyForm1.Edit1.Text := Edit2.Text;
  23. end;

  24. end.
复制代码


在 Unit1 中:

  1. unit Unit1;

  2. interface

  3. uses
  4.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Unit2; // 也需要 uses Unit2

  5. type
  6.   TForm1 = class(TForm)
  7.     Edit1: TEdit;
  8.     Button1: TButton;
  9.     procedure Button1Click(Sender: TObject);
  10.   private
  11.     Form2: TForm2; // 声明 Unit2 的窗体变量
  12.   public
  13.     { public declarations }
  14.   end;

  15. implementation

  16. procedure TForm1.Button1Click(Sender: TObject);
  17. begin
  18.   // 创建并显示 Unit2 的窗口
  19.   Form2 := TForm2.Create(nil);
  20.   try
  21.     // 关键一步:将当前 Unit1 的实例(Self)传给 Unit2
  22.     Form2.MyForm1 := Self;
  23.     Form2.ShowModal; // 或使用 Show 方法,取决于你的需求
  24.   finally
  25.     Form2.Free; // 如果是 ShowModal,通常这样释放
  26.   end;
  27. end;

  28. end.
复制代码


注意事项:
*   确保 Unit1 和 Unit2 的窗体类名正确(示例中为 TForm1TForm2)。
*   ShowModal 会阻塞直到窗口关闭,适合需要等待用户操作的场景;Show 则非阻塞。根据你的需求选择。
*   示例中使用了属性 (property) 来传递引用,你也可以在 Unit2 中定义一个公共方法(如 SetForm1)来完成同样的工作。
*   这种方式直接操作了另一个窗体的控件,在简单程序中可以。对于更复杂的项目,建议在 Unit1 中提供公共方法(如 SetEditText)来设置文本,这样封装性更好。

这样修改后,Unit2 就能将数据传回给 Unit1 了。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 22:19 | 显示全部楼层
本帖最后由 zzzzzzz7 于 2025-12-6 22:20 编辑
FishC 发表于 2025-12-6 21:12
鱼油你好!

你的问题是关于两个窗口之间数据双向传递的。从代码看,Unit2 已经 uses 了 Unit1,所以从 U ...


unit Unit2;

{$mode ObjFPC}{$H+}

interface
//uses Unit1;
//uses Unit1   ;  //如果我把 unit1写出来就会报错
uses
  Classes,SysUtils, Forms, Controls, Graphics, Dialogs,StdCtrls; //<--

type

  { TForm2 }

  TForm2 = class(TForm)
    Button1: TButton;
    F2Edit1: TEdit;
    f2Edit2: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
     // 定义一个变量,用于保存 Unit1 的窗口实例
    FMyForm1: TForm1;           //错误出现
  public
    // 一个公共属性或方法,用于接收来自 Unit1 的引用
    property MyForm1: TForm1 write;          //错误出现

  end;
                                                      

//编译项目,目标:G:\AAApascaltext\project1.exe: 退出代码1,错误: 4
unit2.pas(25,15) Error: Identifier not found "TForm1"
unit2.pas(25,21) Error: Error in type definition
unit2.pas(28,23) Error: Identifier not found "TForm1"
unit2.pas(28,35) Error: Illegal symbol for property access
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 22:20 | 显示全部楼层
zzzzzzz7 发表于 2025-12-06 22:19
FishC 发表于 2025-12-6 21:12
鱼油你好!

你的问 ...


你的代码显示 Unit2 没有在 interface 部分使用 Unit1,这是正确的做法。要解决双向传递问题,你可以按照下面的方法修改:

首先在 Unit2 中:
1. 定义一个变量来存储 Unit1 的引用
2. 创建一个属性或方法来接收这个引用

修改后的 Unit2 代码:

unit Unit2;

{$mode ObjFPC}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;

type
  TForm2 = class(TForm)
    f2Edit1: TEdit;
    f2Edit2: TEdit;
    Button1: TButton;  // 添加一个按钮来测试传回数据
    procedure Button1Click(Sender: TObject);
  private
    // 添加一个私有变量来存储 Unit1 的引用
    FMyForm1: TObject; // 或者更具体的类型
  public
    // 公共属性,用于设置 Form1 的引用
    property MyForm1: TObject write FMyForm1;
  end;

var
  Form2: TForm2;

implementation

{$R *.lfm}

procedure TForm2.Button1Click(Sender: TObject);
var
  Form1Ref: TForm; // 根据实际情况调整类型
begin
  // 将数据传回 Unit1
  if Assigned(FMyForm1) then
  begin
    // 需要将 FMyForm1 转换为正确的类型
    // 这里假设 FMyForm1 是 TForm1 类型
    Form1Ref := TForm(FMyForm1);
   
    // 如果知道具体的控件名,可以这样设置
    // 注意:这里需要访问 Unit1 中的控件
    // 你可以使用 with 语句,或者更好的方式是:
    // 在 Unit1 中创建一个公共方法来接收数据
   
    // 示例:将数据传回 Unit1 的某个 Edit
    // (Form1Ref as TForm1).Edit1.Text := f2Edit1.Text;
   
    // 为了安全起见,我们可以使用 RTTI 或者更好的设计模式
  end;
end;

end.

更安全的方式是在 Unit1 中创建一个公共方法:

首先,修改 Unit1:

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Unit2;

type
  TForm1 = class(TForm)
    // ... 你的控件声明
    Edit1: TEdit;
    Edit4: TEdit;
    Edit5: TEdit;
    Button4: TButton;
    procedure Button4Click(Sender: TObject);
  private
    { private declarations }
  public
    // 添加一个公共方法来接收 Unit2 传来的数据
    procedure ReceiveDataFromUnit2(const AData: string);
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

procedure TForm1.Button4Click(Sender: TObject);
begin
  // 将数据传给 Unit2 并显示 Unit2
  if not Assigned(Form2) then
    Form2 := TForm2.Create(nil);
  
  // 将当前 Form1 的引用传给 Form2
  Form2.MyForm1 := Self;
  
  // 传递数据
  Form2.f2Edit1.Text := Edit4.Text;
  Form2.f2Edit2.Text := Edit5.Text;
  
  Form2.Show;
end;

procedure TForm1.ReceiveDataFromUnit2(const AData: string);
begin
  // 接收来自 Unit2 的数据
  Edit1.Text := AData; // 或者任何你想设置的控件
end;

end.

然后,修改 Unit2 的 Button1Click 方法:

procedure TForm2.Button1Click(Sender: TObject);
begin
  // 调用 Unit1 的公共方法来传递数据
  if Assigned(FMyForm1) then
  begin
    // 安全地调用公共方法
    // 这里假设 FMyForm1 是 TForm1 类型
    (FMyForm1 as TForm1).ReceiveDataFromUnit2(f2Edit1.Text);
  end;
end;

关键点总结:
1. 在 Unit1 中创建 Unit2 时,将 Self(当前 Unit1 实例)传递给 Unit2
2. 在 Unit2 中存储这个引用
3. 通过这个引用调用 Unit1 的公共方法来传递数据
4. 这样可以避免循环引用问题,同时实现双向数据传递

这样修改后,Unit2 就能将数据传回 Unit1 了。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-12-7 03:34

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表