2012-05-02 15 views
5

Empecé a aprender Delphi hace dos días pero me quedé atascado. Me derrumbé porque nada va en mi dirección, así que decidí escribir aquí. Quería crear una clase que tuviera un campo con su propio objeto TTimer y que realizara alguna acción en algún intervalo de tiempo. ¿Es posible? Supongamos que tenemos dicho código:¿Puede el objeto TTimer ser un campo de una clase Delphi?

Sth = class 
private 

public 
    clock:TTimer; 
    procedure clockTimer(Sender: TObject); 
    constructor Create(); 
end; 

constructor Sth.Create() 
begin 
    clock.interval:=1000; 
    clock.OnTimer := clockTimer; 
end; 

procedure Sth.clockTimer(Sender: TObject); 
begin 
    //some action on this Sth object at clock.interval time... 
end; 

Mi código similar copia pero no funciona correctamente. Cuando llamo al constructor, el programa falla (violación de acceso en la línea: clock.interval: = 1000;). No sé qué

Sender:TObject 

pero creo que ese no es el problema. ¿Es posible crear esa clase que quiero?

+0

Los TTimers son con mucha frecuencia campos de clases Delphi. Las clases de formulario son clases, y cada vez que coloca un TTimer en un formulario, el IDE declara un campo TTimer para usted. –

+0

Sé que IDE declara campo TTimer para mí cuando lo pongo en un formulario. Pero quería poner TTimer como un campo de clase que no tiene forma. Quería escribir una clase separada (archivo * .pas) sin un formulario y vincularlo al formulario principal. Entonces, sin forma, tuve que escribir todas las declaraciones por mi cuenta. No sé si es un buen enfoque (no usar formulario con clases secundarias), ni siquiera sé de formas todavía. Pero ahora todo funciona bien después de la respuesta de David Heffernan. – xan

+0

Este problema básico (no sabías que tienes que crear objetos antes de usarlo) me indica que podrías beneficiarte leyendo material básico, como los primeros capítulos de uno de los grandes libros viejos de Delphi, como el Marco cantu. uno (dominio de Delphi 7 o algo así), o al menos, pasar más tiempo en http://www.delphibasics.co.uk/ –

Respuesta

12

No ha creado el temporizador. Declarar una variable no es suficiente. Usted necesita crear el temporizador.

constructor Sth.Create() 
begin 
    clock := TTimer.Create(nil); 
    clock.interval:=1000; 
    clock.OnTimer := clockTimer; 
end; 

Y deberías destruirlo también. Añadir un destructor de la clase

destructor Destroy; override; 

e implementarlo como esto

destructor Sth.Destroy; 
begin 
    clock.Free; 
    inherited; 
end; 

También recomendaría que hacer que su campo clock tiene visibilidad privada. No es bueno exponer los aspectos internos de una clase como esa.

TMyClass = class 
private 
    FClock: TTimer; 
    procedure ClockTimer(Sender: TObject); 
public 
    constructor Create; 
    destructor Destroy; override; 
end; 
.... 
constructor TMyClass.Create 
begin 
    inherited; 
    FTimer := TTimer.Create(nil); 
    FTimer.Interval := 1000; 
    FTimer.OnTimer := ClockTimer; 
end; 

destructor TMyClass.Destroy; 
begin 
    FTimer.Free; 
    inherited; 
end; 

Tenga en cuenta que he incluido llamadas al constructor heredado y al destructor. Estos no son necesarios en esta clase ya que deriva directamente de TObject y el constructor y destructor para TObject está vacío. Pero si cambias la herencia en algún momento y haces que tu clase provenga de una clase diferente, entonces necesitarás hacer esto. Entonces, en mi opinión, es una buena práctica incluir estas llamadas siempre.

+0

la línea: clock: = TTimer.Create; no compila Dice: "No hay suficientes parámetros reales". – xan

+0

Ahora todo está bien. Pero la última pregunta: ¿Por qué TTimer.Create (nil)? ¿Qué tan importante es nil aquí? ¿Por qué tenemos que escribirlo? ¡Muchas muchas gracias! :-) – xan

+3

El constructor recibe un parámetro llamado Propietario de tipo TComponent. Si su clase se deriva de 'TComponent', podría pasar' Self' y entonces su instancia sería * own * the timer. Eso significa que el temporizador se destruirá automáticamente cuando su propietario sea destruido. Esto se usa ampliamente en el VCL. No es necesario aquí, así que pasa 'nil' para optar por el mecanismo de propiedad. –

Cuestiones relacionadas