假设我在delphi项目中有两个表单,我希望能够从form2访问form1的变量.是否有人声明,在form1中可以从所有表单中读取一个"公共"变量?
我试过在公共声明中添加一个变量
{ private declarations }
public
{ public declarations }
test: integer;
end;
Run Code Online (Sandbox Code Playgroud)
在形式2我有
unit Unit2;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, unit1;
type
{ TForm2 }
TForm2 = class(TForm)
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure FormCreate(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.lfm}
{ TForm2 }
procedure TForm2.FormCreate(Sender: TObject);
begin
form1 //<---------- DOES NOT GET RECOGNIZED
end;
end.
Run Code Online (Sandbox Code Playgroud)
然后我将'Unit1'放入Form2的使用部分,但由于循环引用,我似乎无法做到这一点.如果可能的话,我想不要使用指针.
Dis*_*ned 22
首先,最好假装根本不存在全局变量.如果你开始使用全局变量的拐点编程,你将只是避免学习允许你不用它们的非常简单的技术.你担心使用指针(实际上根本不会帮助你解决问题),但不关心使用实际上更危险的全局变量.
全球是危险的,因为:
通函参考
请仔细阅读我对上一个问题的回答,以便更全面地处理循环引用.
在您的情况下,您只需Unit1要从interface使用转移到implementation使用.
var
Form2: TForm2;
implementation
uses
Unit1;
{$R *.lfm}
{ TForm2 }
procedure TForm2.FormCreate(Sender: TObject);
begin
Form1.test; //Is now accessible, but remember: it will cause a runtime error if Form1 hasn't been created or has already been destroyed.
end;
Run Code Online (Sandbox Code Playgroud)
没有全局变量共享数据
你会注意到技术上你还在使用全局变量; 尽管是由Delphi创建的,而不是您自己创建的.这是一种可用于以更受控制的方式共享数据的技术.
unit Unit3;
interface
type
TSharedData = class(TObject)
public
Test1: Integer;
Test2: Integer;
end;
Run Code Online (Sandbox Code Playgroud)
然后在Form1你添加以下内容:
implementation
uses
...
Unit3;
type
TForm1 = class(TForm)
...
public
SharedData: TSharedData;
end;
//Inside either the constructor or OnCreate event add the following line:
SharedData := TSharedData.Create;
//Inside either the destructor or OnDestroyevent add the following line:
SharedData.Free;
Run Code Online (Sandbox Code Playgroud)
然后在Form2你做一些稍微不同的事情,因为你想使用Form1的共享数据而不是它自己的"共享数据".
implementation
uses
...
Unit3;
type
TForm2 = class(TForm)
...
public
Form1SharedData: TSharedData;
end;
//Nothing added to constructor/destructor or OnCreate/OnDestroy events
Run Code Online (Sandbox Code Playgroud)
最后,在创建两种形式后,你给Form2一个refernce到Form1的共享数据:
procedure RunApplicationWithoutFormGlobals;
var
LForm1: TForm1;
LForm2: TForm2;
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, LForm1);
Application.CreateForm(TForm2, LForm2);
LForm2.Form1SharedData := LForm1.SharedData;
Application.Run;
end;
Run Code Online (Sandbox Code Playgroud)
上面说明了即使是Delphi的全局变量也可以轻松消除.
免责声明:有些代码通常采用封装原则,但仅供说明之用.
War*_* P 16
首先,如果你必须使用全局变量(最好不要使用全局变量,正如Craig明智地指出的那样)那么你应该在SharedGlobals.pas中放置你想要分享的全局变量:
unit SharedGlobals;
interface
var
{variables here}
Something:Integer;
implementation
{ nothing here?}
Run Code Online (Sandbox Code Playgroud)
现在使用该单元,从您想要共享访问该变量的两个单元中.或者,同时引用另一个对象,该对象被命名为合理的,并且设计该对象,作为状态的持有者(变量值)这两个实例(表格或类别,或其他)需要分享.
第二个想法,既然你的两个单元已经相互依赖,你也可以通过使用创建循环依赖的单元来解决循环依赖,从实现部分而不是接口:
unit Unit2;
interface
/// stuff
implementation
uses Unit1;
Run Code Online (Sandbox Code Playgroud)
...
unit Unit1;
interface
/// stuff
implementation
uses Unit2;
Run Code Online (Sandbox Code Playgroud)