Recent

Author Topic: type helper not work on qtwidgets when reintroduce existing method  (Read 883 times)

cai

  • New Member
  • *
  • Posts: 44
what I expect is run "WriteLn('TQtWidgetHelper.slotDropFiles ... ');" in the method "slotDropFiles" of  TQtWidgetHelper when I drag and drop a file on form after compile run.

but actually, nothing happen.

"slotDropFiles" is existing in TQtWidget. (lazarus\lcl\interfaces\qt\qtwidgets.pas)

is FPC type helper support to reimplement/reintroduce existing method of class?

if YES, is there some modeswitch need? ({$modeswitch typehelpers}has been tested,and  is not work too)
or other ways to make it work?

test project files are all in attachments, unzip to compile...
hungry for solution, thank!

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. //{$modeswitch ADVANCEDRECORDS}
  6. //{$modeswitch typehelpers}
  7. //{$modeswitch multihelpers}
  8.  
  9. interface
  10.  
  11. uses
  12.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
  13.   Qt4,  qtwidgets;
  14.  
  15. type
  16.  
  17.   { TQtWidgetHelper }
  18.  
  19.   TQtWidgetHelper = class helper for TQtWidget
  20.   public
  21.     function slotDropFiles(Sender: QObjectH; Event: QEventH): Boolean;
  22.   end;
  23.  
  24.   { TForm1 }
  25.  
  26.   TForm1 = class(TForm)
  27.     Memo1: TMemo;
  28.     procedure FormDropFiles(Sender: TObject; const FileNames: array of string);
  29.   private
  30.  
  31.   public
  32.  
  33.   end;
  34.  
  35. var
  36.   Form1: TForm1;
  37.  
  38. implementation
  39.  
  40. {$R *.frm}
  41.  
  42. { TQtWidgetHelper }
  43.  
  44. function TQtWidgetHelper.slotDropFiles(Sender: QObjectH; Event: QEventH
  45.   ): Boolean;
  46. var
  47.   MimeData: QMimeDataH;
  48.   QStrList: QStringListH;
  49.   ByteArr: QByteArrayH;
  50.   i: Integer;
  51.   WStr: WideString;
  52.   GotFiles: Boolean;
  53.   FilesList: TStrings;
  54.   Files: Array of String;
  55.   ParentForm: TCustomForm;
  56.   Url: QUrlH;
  57. begin
  58.   Result := False;
  59.  
  60.   WriteLn('TQtWidgetHelper.slotDropFiles ... ');
  61.  
  62.   GotFiles := False;
  63.   MimeData := QDropEvent_mimeData(QDropEventH(Event));
  64.   QStrList := QStringList_create();
  65.   try
  66.     QMimeData_formats(MimeData, QStrList);
  67.     for i := QStringList_size(QStrList) - 1 downto 0 do
  68.     begin
  69.       QStringList_at(QStrList, @WStr, i);
  70.       GotFiles := (WStr = 'text/plain') or (WStr = 'text/uri-list');
  71.       if GotFiles then
  72.         break;
  73.     end;
  74.   finally
  75.     QStringList_destroy(QStrList);
  76.   end;
  77.   if not GotFiles then
  78.     exit;
  79.   ByteArr := QByteArray_create();
  80.   try
  81.     QMimeData_data(MimeData, ByteArr, @WStr);
  82.     if not QByteArray_isNull(ByteArr) then
  83.     begin
  84.       WStr := QByteArray_constData(ByteArr);
  85.       FilesList := TStringList.Create;
  86.       try
  87.         FilesList.Text := WStr{%H-};
  88.         if (FilesList.Count > 0) and
  89.           ( (FilesList[FilesList.Count-1] = #0)
  90.             or
  91.             (FilesList[FilesList.Count-1] = '') ) then
  92.           SetLength(Files, FilesList.Count - 1)
  93.         else
  94.           SetLength(Files, FilesList.Count);
  95.         for i := 0 to High(Files) do
  96.         begin
  97.           WStr := FilesList{%H-}.Strings[i];
  98.           Url := QUrl_create(@WStr);
  99.           QUrl_toLocalFile(Url, @WStr);
  100.           Files[i] := {%H-}WStr;
  101.           QUrl_destroy(Url);
  102.         end;
  103.       finally
  104.         FilesList.Free;
  105.       end;
  106.       QDropEvent_setDropAction(QDropEventH(Event), QtCopyAction);
  107.       QDropEvent_acceptProposedAction(QDropEventH(Event));
  108.  
  109.       Application.IntfDropFiles(Files);
  110.       if ClassType = TQtMainWindow then
  111.         TCustomForm(LCLObject).IntfDropFiles(Files)
  112.       else
  113.       begin
  114.         ParentForm := TCustomForm(LCLObject.IntfGetDropFilesTarget);
  115.         if ParentForm is TCustomForm then
  116.           ParentForm.IntfDropFiles(Files);
  117.       end;
  118.  
  119.       Result := True;
  120.     end;
  121.   finally
  122.     QByteArray_destroy(ByteArr);
  123.   end;
  124. end;
  125.  
  126. { TForm1 }
  127.  
  128. procedure TForm1.FormDropFiles(Sender: TObject; const FileNames: array of string
  129.   );
  130. begin
  131.   Memo1.Lines.AddStrings(FileNames);
  132. end;
  133.  
  134. end.
  135.  
  136.  

Thaddy

  • Hero Member
  • *****
  • Posts: 16945
  • Ceterum censeo Trump esse delendam
Re: type helper not work on qtwidgets when reintroduce existing method
« Reply #1 on: May 03, 2025, 11:13:33 am »
The modeswitch typehelpers is necessary.
Also modeswitch multihelpers is trunk/main (FPC 3.3.1) only.
The example in the documentation is an example of how to change behavior:
https://www.freepascal.org/docs-html/ref/refse64.html#x124-14800010.1.
Unit order may be important.
« Last Edit: May 03, 2025, 11:27:01 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

cai

  • New Member
  • *
  • Posts: 44
Re: type helper not work on qtwidgets when reintroduce existing method
« Reply #2 on: May 05, 2025, 05:44:44 pm »
The modeswitch typehelpers is necessary.
Also modeswitch multihelpers is trunk/main (FPC 3.3.1) only.
The example in the documentation is an example of how to change behavior:
https://www.freepascal.org/docs-html/ref/refse64.html#x124-14800010.1.
Unit order may be important.

I found that link say " a helper can only use in current scope of code, or add a helper filename in Unit uses "

it mean my reintroduce method slotDropFiles only work in current file (unit1.pas), so TQtWidgetHelper can not effective for the existing slotDropFiles call in Original File qtwidgets.

unless add a helper code, or add a helper unit in uses of qtwidgets.

is there any way to reintroduce slotDropFiles with typehelpers, the implement code is out of file qtwidgets, and without any qtwidgets file modification, I think this helper can be called global-reintroduce-helper.

« Last Edit: May 05, 2025, 05:47:30 pm by cai »

Thaddy

  • Hero Member
  • *****
  • Posts: 16945
  • Ceterum censeo Trump esse delendam
Re: type helper not work on qtwidgets when reintroduce existing method
« Reply #3 on: May 06, 2025, 09:03:45 am »
Helpers can also be inherited.....
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

TRon

  • Hero Member
  • *****
  • Posts: 4369
Re: type helper not work on qtwidgets when reintroduce existing method
« Reply #4 on: May 06, 2025, 09:27:29 am »
is there any way to reintroduce slotDropFiles with typehelpers, the implement code is out of file qtwidgets, and without any qtwidgets file modification, I think this helper can be called global-reintroduce-helper.
No, and the reason for that is exactly as you intend to use it as it would allow for 3th parties to change the behaviour of an existing implementation.
Today is tomorrow's yesterday.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5968
  • Compiler Developer
Re: type helper not work on qtwidgets when reintroduce existing method
« Reply #5 on: May 06, 2025, 08:16:13 pm »
is FPC type helper support to reimplement/reintroduce existing method of class?

Methods of type helpers only hide methods when you explicitly call them. A type helper does not touch the virtual method table of a class instance in any way.

cai

  • New Member
  • *
  • Posts: 44
Re: type helper not work on qtwidgets when reintroduce existing method
« Reply #6 on: May 10, 2025, 10:16:54 am »
No, and the reason for that is exactly as you intend to use it as it would allow for 3th parties to change the behaviour of an existing implementation.

 :)OK, this reason is acceptable.
but I think the compiler can be more useful if it can do some patch code to fix or enhance with typehelpers feature, when the existing implementation is opensource in the coding time.
in this topic to fix problem, I can copy qtwidgets.pas to my project path, and then modify -> recompile, or modify the Original File qtwidgets.pas, because the widgets qt4 interface code is open in LCL, I think this change behavioir can be allowed. and can be easier if typehelpers support to.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5968
  • Compiler Developer
Re: type helper not work on qtwidgets when reintroduce existing method
« Reply #7 on: May 11, 2025, 04:38:33 pm »
but I think the compiler can be more useful if it can do some patch code to fix or enhance with typehelpers feature, when the existing implementation is opensource in the coding time.
in this topic to fix problem, I can copy qtwidgets.pas to my project path, and then modify -> recompile, or modify the Original File qtwidgets.pas, because the widgets qt4 interface code is open in LCL, I think this change behavioir can be allowed. and can be easier if typehelpers support to.

No, that's not what the purpose and use case of type helpers is. Not to mention if the method in question is not virtual it would in fact be impossible for the compiler to do, because the units are precompiled from the compiler's point of view.

 

TinyPortal © 2005-2018