Eventloop?!?

Forum für alles rund um die MSEide und MSEgui

Eventloop?!?

Beitragvon fliegermichl » 9. Jan 2018, 14:25 Eventloop?!?

Ich habe hier irgendwie einen zirkulären Eventloop gebastelt und weiss nicht so recht, wie ich das lösen kann?
Das Programm funktioniert aber ruft das Paintbox.onPaint irgendwie zirkulär auf. (Der Debugserver bekommt in einer Tour "Painiting" obwohl die Maus gar nicht bewegt wird. Danz ganze pausiert erst dann, wenn man die Maus aus der Paintbox rausschiebt. Ich muss aber auf die Bewegung der Maus mit neuzeichnen der Paintbox reagieren.

Code: Alles auswählen
 
unit main;
{$ifdef FPC}{$mode objfpc}{$h+}{$endif}
interface
uses
 msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui,
 msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms,msedock,
 msedockpanelform,msesimplewidgets, dbugintf;
 
type
 tmymousehandler = class
 private
  startx, starty,
  fx, fy : integer;
  fdown : boolean;
 public
  procedure mymousemove(sender : twidget; var ainfo : mouseeventinfoty);
  procedure mymousedown(sender : tobject; var ainfo : mouseeventinfoty);
  procedure mymouseup(sender : tobject; var ainfo : mouseeventinfoty);
  procedure mymousehandler(const sender : twidget; var ainfo : mouseeventinfoty);
  procedure mypaint(sender : tobject; Canvas : TCanvas);
 end;
 
 tmainfo = class(tdockpanelform)
   pb: tpaintbox;
   procedure formcreate(const sender: TObject);
   procedure pbpaint(const sender: twidget; const acanvas: tcanvas);
 private
  fHandler : tmymousehandler;
 end;
var
 mainfo: tmainfo;
implementation
uses
 main_mfm;
{ tmymousehandler }
 
procedure tmymousehandler.mymousemove(sender: twidget;
               var ainfo: mouseeventinfoty);
begin
 fx := ainfo.pos.x;
 fy := ainfo.pos.y;
 sender.invalidate;
end;
 
procedure tmymousehandler.mymousedown(sender: tobject;
               var ainfo: mouseeventinfoty);
begin
 fdown := true;
 startx := ainfo.pos.x;
 starty := ainfo.pos.y;
end;
 
procedure tmymousehandler.mymouseup(sender: tobject;
               var ainfo: mouseeventinfoty);
begin
 fdown := false;
end;
 
procedure tmymousehandler.mymousehandler(const sender: twidget;
               var ainfo: mouseeventinfoty);
begin
 case ainfo.eventkind of
  ek_mousemove : mymousemove(sender, ainfo);
  ek_buttonpress : mymousedown(sender, ainfo);
  ek_buttonrelease : mymouseup(sender, ainfo);
 end;
end;
 
 
 
procedure tmymousehandler.mypaint(sender: tobject; Canvas: TCanvas);
begin
 SendDebug('painting');
 if fdown then
 begin
  canvas.color := cl_black;
  canvas.drawline(mp(startx, starty), mp(fx, fy));
 end;
end;
 
procedure tmainfo.formcreate(const sender: TObject);
begin
 fHandler := TMyMouseHandler.Create;
 pb.onmouseevent := @fhandler.mymousehandler;
 
end;
 
procedure tmainfo.pbpaint(const sender: twidget; const acanvas: tcanvas);
begin
 fhandler.mypaint(sender, acanvas);
end;
 
end.
 
fliegermichl
 
Beiträge: 202
Registriert: 9. Jun 2011, 08:42

Beitragvon mse » 9. Jan 2018, 15:29 Re: Eventloop?!?

fliegermichl hat geschrieben:Ich habe hier irgendwie einen zirkulären Eventloop gebastelt und weiss nicht so recht, wie ich das lösen kann?

Kann ich nicht nachvollziehen. Allerdings habe ich debugwriteln() aus msesysutils verwendet:
Code: Alles auswählen
 
procedure tmymousehandler.mypaint(sender: tobject; Canvas: TCanvas);
begin
//SendDebug('painting');
 inc(fcount);
 debugwriteln(inttostr(fcount)+' painting');
 if fdown then
 begin
  canvas.color := cl_black;
  canvas.drawline(mp(startx, starty), mp(fx, fy));
 end;
end;
 

MSEgui hat TObjectPicker um solche Aufgaben zu lösen, ein Anwendungsbeispiel ist TXYChartEdit aus tab widget.
mse
 
Beiträge: 1986
Registriert: 16. Okt 2008, 09:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0) | 
CPU-Target: x86,x64,ARM
Nach oben

Beitragvon fliegermichl » 9. Jan 2018, 16:23 Re: Eventloop?!?

Das ist interessant. Mit debugwriteln geht es bei mir auch.

Wie dem auch sei. so habe ich wenigstens einen Weg meine Anwendung zu debuggen. Solche Sachen sind ohnehin immer schwierig zu debuggen wo der Debugger das Verhalten der Anwendung beeinflusst.
fliegermichl
 
Beiträge: 202
Registriert: 9. Jun 2011, 08:42

Beitragvon AndreasMR » 9. Jan 2018, 20:00 Re: Eventloop?!?

Hallo Fliegermichl,


fliegermichl hat geschrieben:Ich habe hier irgendwie einen zirkulären Eventloop gebastelt und weiss nicht so recht, wie ich das lösen kann?
Ich muss aber auf die Bewegung der Maus mit neuzeichnen der Paintbox reagieren.


Was lässt Dich glauben, dass Du das musst?

Neuzeichnen musst Du doch erst, wenn irgendein Ereignis passiert ist, irgendwas angeklickt oder losgelassen wurde. Wenn Du bei jedem Pixel, den sich die Maus bewegt, irgendwas (Größeres) neuzeichnest, dann hieße das bei Bewegung 50 Pixel schräg bewegt bereits 100 x Neuzeichnen. Das schafft keine noch so gute Routine.

Suche Dir ein anderes Ereignis, das das Neuzeichnen auslösen sollst - und Dein Programm wird rasend schnell werden.

Das ist z.B. auch der Grund, weshalb bei "Sizing"-Ereignissen ein Filter gesetzt wird. Erst wenn die Maus zum Stillstand gekommen ist, wird die Größenänderung eines Fensters vorgenommen (alte Größe auf neue Größe) - und nicht bei jeder einzelnen temporären Größenänderung. Solange die Maus nicht losgelassen wurde, gilt ein Ereignis als nicht abgeschlossen, um ein Ereignis auslösen zu dürfen.


Beste Grüße

Andreas
Ubuntu 14.04 LTS / Raspbian / Windows: Lazarus ab 0.9 bis 3.0
AndreasMR
 
Beiträge: 86
Registriert: 4. Aug 2015, 14:29
OS, Lazarus, FPC: Linux, Raspbian, Windows | 
CPU-Target: 64/32 Bit
Nach oben

Beitragvon mse » 9. Jan 2018, 20:18 Re: Eventloop?!?

MSEgui überspringt aufgelaufene mousemove events und verarbeitet lediglich den letzten. Zu dem wird update() erst aufgerufen wenn die event queue leer ist. Von daher ist das invalidisieren des widgets in onmouseevent schon möglich. Ich empfehle trotzdem die beweglichen Elemente mit canvas.rasterop rop_xor zu zeichnen und nicht das widget zu invalidisieren welches dann komplett neu gezeichnet werden muss. TObjectPicker bietet die Infrastruktur dazu.
mse
 
Beiträge: 1986
Registriert: 16. Okt 2008, 09:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0) | 
CPU-Target: x86,x64,ARM
Nach oben

Beitragvon fliegermichl » 11. Jan 2018, 09:24 Re: Eventloop?!?

AndreasMR hat geschrieben:Hallo Fliegermichl,


fliegermichl hat geschrieben:Ich habe hier irgendwie einen zirkulären Eventloop gebastelt und weiss nicht so recht, wie ich das lösen kann?
Ich muss aber auf die Bewegung der Maus mit neuzeichnen der Paintbox reagieren.


Was lässt Dich glauben, dass Du das musst?

Neuzeichnen musst Du doch erst, wenn irgendein Ereignis passiert ist, irgendwas angeklickt oder losgelassen wurde. Wenn Du bei jedem Pixel, den sich die Maus bewegt, irgendwas (Größeres) neuzeichnest, dann hieße das bei Bewegung 50 Pixel schräg bewegt bereits 100 x Neuzeichnen. Das schafft keine noch so gute Routine.

Suche Dir ein anderes Ereignis, das das Neuzeichnen auslösen sollst - und Dein Programm wird rasend schnell werden.

Das ist z.B. auch der Grund, weshalb bei "Sizing"-Ereignissen ein Filter gesetzt wird. Erst wenn die Maus zum Stillstand gekommen ist, wird die Größenänderung eines Fensters vorgenommen (alte Größe auf neue Größe) - und nicht bei jeder einzelnen temporären Größenänderung. Solange die Maus nicht losgelassen wurde, gilt ein Ereignis als nicht abgeschlossen, um ein Ereignis auslösen zu dürfen.


Beste Grüße

Andreas


Wenn der Anwender in dem CAD Programm ein Gebäude mit der Maus verschiebt, muss ich ihm schon anzeigen wo er es gerade hingeschoben hat :-)
fliegermichl
 
Beiträge: 202
Registriert: 9. Jun 2011, 08:42

Beitragvon Socke » 11. Jan 2018, 09:34 Re: Eventloop?!?

fliegermichl hat geschrieben:Wenn der Anwender in dem CAD Programm ein Gebäude mit der Maus verschiebt, muss ich ihm schon anzeigen wo er es gerade hingeschoben hat :-)

Wenn das Bild mit einer definierten Frequenz (z.B. 60 Hz oder 120 Hz) aktualisiert wird, sollte das hoffentlich ausreichen.
Beim Mausverschieben speicherst du also nur die neue Mausposition und kannst dann in einem Timer-Event oder sogar separaten Thread das neue Bild berechnen.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Socke
 
Beiträge: 2546
Registriert: 22. Jul 2008, 18:27
Wohnort: Köln
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 8.1/Debian GNU/Linux/Raspbian/openSUSE | 
CPU-Target: 32bit x86 armhf
Nach oben

Beitragvon fliegermichl » 11. Jan 2018, 09:43 Re: Eventloop?!?

mse hat geschrieben:MSEgui überspringt aufgelaufene mousemove events und verarbeitet lediglich den letzten. Zu dem wird update() erst aufgerufen wenn die event queue leer ist. Von daher ist das invalidisieren des widgets in onmouseevent schon möglich. Ich empfehle trotzdem die beweglichen Elemente mit canvas.rasterop rop_xor zu zeichnen und nicht das widget zu invalidisieren welches dann komplett neu gezeichnet werden muss. TObjectPicker bietet die Infrastruktur dazu.


Das erklärt auch, weshalb meine eigene Erkennung von aufgelaufenen MouseEvents nicht gegriffen hat :-)

Übrigens, dass ich dich hier in letzter Zeit mit Fragen bombardiert habe, mag den Eindruck erwecken, daß ich nicht mit mseGUI zufrieden bin. Dem ist mitnichten so. Ich halte es für ein ganz tolles ausgereiftes und wahnsinnig schnelles System. Ausserdem die fehlenden Abhängigkeiten zu irgendwelchen WidgetSets macht es unglaublich viel besser nachvollziehbar.

auch solcher Mist wie bei Lazarus "External Exception segfault" mit einem so aussagelosem Stacktrace der nur Fragezeichen beinhaltet ist mir hier noch nie passiert.

Einzig die Dokumentation ist etwas dürftig.
fliegermichl
 
Beiträge: 202
Registriert: 9. Jun 2011, 08:42

• Themenende •

Zurück zu MSEide und MSEgui



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

cron
porpoises-institution
accuracy-worried