Jump to content

shineworld

Members
  • Content Count

    304
  • Joined

  • Last visited

  • Days Won

    3

shineworld last won the day on November 1 2022

shineworld had the most liked content!

Community Reputation

73 Excellent

About shineworld

  • Birthday 05/09/1970

Technical Information

  • Delphi-Version
    Delphi 12 Athens

Recent Profile Visitors

2757 profile views
  1. shineworld

    What is the best AI at Delphi

    You can "teach" chatgpt with tags to avoid to repeat same things, eg: to chatgpt > When I use tag #DCODE you have to create a clean Delphi code as in followed text description adding short comments which does not use capital letter, eg: // sort the list, etc etc etc. So you can ask: > #DCODE create an alphabetical acending and descending sort of a TList<string> object.
  2. shineworld

    union with bitfields

    PERFECT is just what I need....
  3. shineworld

    union with bitfields

    Hi all. I've to convert a Builder C++ code to Delphi which uses bitfiels in union and I don't know where to start and if it is possible: // define QCL data types typedef short QCL_WORD; typedef union { QCL_WORD data; struct { QCL_WORD alarm_state :1; // bus flags: alarm state QCL_WORD alignment_state :1; // bus flags: alignment state QCL_WORD inversion_wait :1; // bus flags: external synchronism - inversion wait QCL_WORD out_of_min_bound :1; // bus flags: column position is out of minimum boundaries QCL_WORD out_of_max_bound :1; // bus flags: column position is out of maximum boundaries QCL_WORD below_safety_height :1; // bus flags: column position is below safety height QCL_WORD in_working_pos :1; // bus flags: column position is in working position QCL_WORD locking_latch_state :1; // bus flags: column position in locking latch state QCL_WORD battery_warning :1; // bus flags: column in battery warning QCL_WORD battery_alarm :1; // bus flags: column in battery alarm QCL_WORD evr_state :1; // bus flags: column EVR state QCL_WORD load_weight_zone :2; // bus flags: column in load weight zone QCL_WORD column_is_consistent :1; // bus flags: column in load weight zone QCL_WORD lift_set_acquire_req :1; // bus flags: columns lift set acquire request QCL_WORD movement_mode_absolute :1; // bus flags: column has movement mode absolute } fields; } t_bus_flags_w4; Thanks in advance for any suggestion. Best regards
  4. shineworld

    DelphiVCL TreeView OnCustomDrawItem

    New commit fixes the issue and works perfectly.
  5. I found an oddity in the "state" field of the OnCustomDrawItem event. Basically instead of reporting the states of the VCL control passed by the related event all possible states are passed there: function CustomDrawStateToPython(const ACustomDrawState: TCustomDrawState): PPyObject; procedure Append(const AList: PPyObject; const AString: string); var LItem: PPyObject; begin with GetPythonEngine do begin LItem := PyUnicodeFromString(AString); PyList_Append(AList, LItem); Py_XDecRef(LItem); end; end; var LCompType: PTypeInfo; LMin: integer; LMax: integer; LState: integer; begin Result := GetPythonEngine().PyList_New(0); LCompType := GetTypeData(TypeInfo(TCustomDrawState)).CompType^; LMin := LCompType^.TypeData^.MinValue; LMax := LCompType^.TypeData^.MaxValue; for LState := LMin to LMax do Append(Result, GetEnumName(LCompType, LState)); // <-- all enums are always set to state python attribute end; In my TreeView, when a node is selected, I've to change to white the font color otherwise text is hard to be sight: Either I completely misunderstood the functionality of that function or there was an oversight. Unfortunately Vcl.ComCtrls TCustomDrawItem is defined as a set with direct enumerators in the set so I didn't find a direct method to do: if CAST_TO_ENUM(LState) in TCustomDrawState then but with a forcing and a pointer you still get something working: function CustomDrawStateToPython(const ACustomDrawState: TCustomDrawState): PPyObject; procedure Append(const AList: PPyObject; const AString: string); var LItem: PPyObject; begin with GetPythonEngine do begin LItem := PyUnicodeFromString(AString); PyList_Append(AList, LItem); Py_XDecRef(LItem); end; end; function IsBitSet(Index: Integer; State: TCustomDrawState): Boolean; var P: PByte; begin if (Index < 0) or (Index >= SizeOf(TCustomDrawState) * 8) then Exit(False); P := @State; Result := (P^ and (1 shl Index)) <> 0; end; var LCompType: PTypeInfo; LMin: integer; LMax: integer; LState: integer; begin Result := GetPythonEngine().PyList_New(0); LCompType := GetTypeData(TypeInfo(TCustomDrawState)).CompType^; LMin := LCompType^.TypeData^.MinValue; LMax := LCompType^.TypeData^.MaxValue; for LState := LMin to LMax do begin if IsBitSet(LState, ACustomDrawState) then Append(Result, GetEnumName(LCompType, LState)); end; end; I'm not so smart in these things so if some Delphi guru has a better solution I'm ready to fix the code. Best regards.
  6. shineworld

    PyScripter - Integration with LLM

    Incredible work. Just one question. I have tried several times to install the 5.0.0 Beta version via the Upgrade Check function getting always getting the error "File download failed.
  7. shineworld

    Owner receives only Delphi objects

    Missing attachment from past post. delphivcl_ext.zip
  8. I need some help from Python + DelphiVCL guru. Some time ago I've made a new DelphiVCL control to use VTK with Python + VCL + VTK. To do that I've modified the Embarcadero's DelphiVCL package to add new control, called new library as cnc_vision_vcl to not override already installad DelphiVCL library and all worked fine. But I don't want to have a custom DelphiVCL and so I've tried to move the component in a delphivcl_ext project and at now same code does not work. What I've to in native Delphivcl code (which works) Create a clone of DelphiVCL projects as cnc_vision_vcl. Created new component WrapExtVTK.pas (attached). Modified source\vcl\WrapVclControls to import new unit: uses WrapDelphiTypes, WrapDelphiClasses, WrapDelphiWindows, WrapDelphiDataBind, WrapActions, WrapVclImgList, WrapVclControls, WrapVclGraphics, WrapVclForms, WrapVclActnList, WrapVclMenus, WrapVclStdCtrls, WrapVclComCtrls, WrapVclExtCtrls, WrapVclButtons, WrapVclGrids, WrapVclSamplesSpin, WrapVclWinXCtrls, WrapVclThemes, WrapVclDialogs, WrapVclMedia, WrapExtVTK; // <--- new unit Compiled and used new cnc_vision_vcl.pyd file In the cnc_vision_vcl a zip with working test All work fine but I want to move component in an "ext"tra package to leave untouched original delphivcl, so I've created a clean project which add almost the same code but when I try to create the VTKPanel object I obtains: self.vtk_panel = VTKPanel(self) ^^^^^^^^^^^^^^ AttributeError: Owner receives only Delphi objects In next chat the zip of entire project because I've reached post limits. WrapExtVTK.pas cnc_vision_vcl.zip
  9. shineworld

    DelphiVCL4Python

    Everything described by pyscripter is pure truth. I came to Python because of the need to use OpenCV with Delphi in analyzing frames from camera. There are a couple of wrapper libraries for OpenCV, but when I tried them they were more pains than joys. I then learned about DelphiVCL for python and that fixed the damaging issue of a good UI in Python. The whole phase of capturing frames from IP camera via Python was a bloodbath, too slow and blocking, even using in threads that are not parallel anyway. But Python4Delphi gave me the ability to "move" the heavy, parallel processing into Delphi threads. So I moved the camera communication and frame retrieval into a Delphi class using threads and Indy then exported to Python with P4D, quietly getting the required 30fps. I was then free to use the full power of OpenCV + Skia 4 Python + DelphiVCL + Cython to get a really high performance image processing framework. Yes python can be fast if you roll with it. Obviously doing everything native in Delphi would be another thing...but it is known that importing libraries written in C++ is still impossible, except in rare cases where someone creates a wrapper in C with undoubted complexity of use.
  10. shineworld

    DelphiVCL4Python

    You can greatly improve the speed of a python script by passing it through Cython and obtaining compiled pyd (windows dll) or .so (linux library) output modules that can then be imported without any modification into the original code. I use Cython a lot. At the end of a project, through a script, I "cython" all the .py modules to get a version more performant and difficult to reverse engineer. In the middle Cython convert .py to .c and compile to pyd using MSCV or any other C++ compiler.
  11. shineworld

    VTK in DelphiVCL or DelphiFMX

    OK, I can understand the reasons for this. In my suite I will deploy a custom delphivcl renamed with a different name to avoid any collision with the native version of Embarcadero and installed in python as an offline whl package. The important thing for me was the ability to REMOVE the use of QT and be able to use the VTK 3D management package. At 90% I only program with Delphi, and Python + DelphiVCL + VTK is only for me to create support and research programs. At the end of it all I posted my solution so if anyone else finds themselves in need of using DelphiVCL + VTK they have a starting point for doing so.
  12. shineworld

    VTK in DelphiVCL or DelphiFMX

    To fully integrate VTK I had to modify the DelphiVCL sources of Python4Delphi by adding a new VTKPanel class inherited from TCustomControl that exposes OnMouseDown, OnMouseMove, OnMouseUp, OnMouseWheel, OnResize, and OnPaint: {*** * TAKE CARE * ========= * This units add extra components to integrate VTK. * **} {$I ..\Definition.Inc} unit WrapExtVTK; interface uses System.Classes, System.TypInfo, System.SysUtils, Winapi.Windows, Vcl.Controls, Vcl.Graphics, Vcl.StdCtrls, WrapDelphi, PythonEngine, WrapVclControls, WrapDelphiClasses; type TVTKPanel = class(TCustomControl) private FOnPaint: TNotifyEvent; protected procedure Paint; override; published property OnPaint: TNotifyEvent read FOnPaint write FOnPaint; published property OnMouseDown; // TMouseEvent property OnMouseMove; // TMouseMoveEvent property OnMouseUp; // TMouseEvent property OnMouseWheel; // TMouseWheelEvent property OnResize; // TNotifyEvent end; TPyDelphiVTKPanel = class (TPyDelphiControl) private function GetDelphiObject: TCustomControl; procedure SetDelphiObject(const Value: TCustomControl); protected public class function DelphiObjectClass : TClass; override; // Properties property DelphiObject: TCustomControl read GetDelphiObject write SetDelphiObject; end; implementation { TVTKPanel } procedure TVTKPanel.Paint; begin inherited; if Assigned(FOnPaint) then FOnPaint(Self); end; { TPyDelphiVTKPanel } class function TPyDelphiVTKPanel.DelphiObjectClass: TClass; begin Result := TVTKPanel; end; function TPyDelphiVTKPanel.GetDelphiObject: TCustomControl; begin Result := TVTKPanel(inherited DelphiObject); end; procedure TPyDelphiVTKPanel.SetDelphiObject(const Value: TCustomControl); begin inherited DelphiObject := Value; end; { register the wrappers, the globals and the constants } type TThirdPartiesCtrlsRegistration = class(TRegisteredUnit) public function Name : string; override; procedure RegisterWrappers(APyDelphiWrapper : TPyDelphiWrapper); override; procedure DefineFunctions(APyDelphiWrapper : TPyDelphiWrapper); override; procedure DefineVars(APyDelphiWrapper : TPyDelphiWrapper); override; end; { TThirdPartiesCtrlsRegistration } procedure TThirdPartiesCtrlsRegistration.DefineFunctions(APyDelphiWrapper: TPyDelphiWrapper); begin inherited; end; procedure TThirdPartiesCtrlsRegistration.DefineVars(APyDelphiWrapper: TPyDelphiWrapper); begin inherited; end; function TThirdPartiesCtrlsRegistration.Name: string; begin Result := 'ThirdPartiesVTK'; end; procedure TThirdPartiesCtrlsRegistration.RegisterWrappers(APyDelphiWrapper: TPyDelphiWrapper); begin inherited; APyDelphiWrapper.RegisterDelphiWrapper(TPyDelphiVTKPanel); end; initialization RegisteredUnits.Add(TThirdPartiesCtrlsRegistration.Create); System.Classes.RegisterClasses([TVTKPanel]); end. At this point now mouse management and window resizing works well, although during Resize there is a small instant where you see the white container window. from DelphiVCL import * from vtkmodules.vtkRenderingCore import vtkRenderWindow from vtkmodules.vtkRenderingUI import vtkGenericRenderWindowInteractor class vclVTKRenderWindowInteractor(VTKPanel): """ A vclVTKRenderWindowInteractor for Python and DelphiVCL. Uses a vtkGenericRenderWindowInteractor to handle the interactions. Use GetRenderWindow() to get the vtkRenderWindow. """ def __init__(self, owner): super().__init__(self, owner) # set default member values self._render_window = None self._render_interactor = None self._render_interactor_timer = None # assign control events self.OnMouseDown = self._on_mouse_down self.OnMouseMove = self._on_mouse_move self.OnMouseWheel = self._on_mouse_wheel self.OnMouseUp = self._on_mouse_up self.OnPaint = self._on_paint self.OnResize = self._on_resize def __getattr__(self, attr): """Makes the object behave like a vtkGenericRenderWindowInteractor""" if attr == '__vtk__': return lambda t=self._render_interactor: t elif hasattr(self._render_interactor, attr): return getattr(self._render_interactor, attr) else: raise AttributeError(self.__class__.__name__ + " has no attribute named " + attr) def _on_mouse_down(self, Sender, Button, Shift, X, Y): ctrl = 'ssCtrl' in Shift shift = 'ssShift' in Shift self._render_interactor.SetEventInformationFlipY(X, Y, ctrl, shift) if Button == 0: self._render_interactor.InvokeEvent("LeftButtonPressEvent") elif Button == 1: self._render_interactor.InvokeEvent("RightButtonPressEvent") elif Button == 2: self._render_interactor.InvokeEvent("MiddleButtonPressEvent") def _on_mouse_move(self, Sender, Shift, X, Y): ctrl = 'ssCtrl' in Shift shift = 'ssShift' in Shift self._render_interactor.SetEventInformationFlipY(X, Y, ctrl, shift, chr(0), 0, None) self._render_interactor.MouseMoveEvent() def _on_mouse_up(self, Sender, Button, Shift, X, Y): ctrl = 'ssCtrl' in Shift shift = 'ssShift' in Shift self._render_interactor.SetEventInformationFlipY(X, Y, ctrl, shift) if Button == 0: self._render_interactor.InvokeEvent("LeftButtonReleaseEvent") elif Button == 1: self._render_interactor.InvokeEvent("RightButtonReleaseEvent") elif Button == 2: self._render_interactor.InvokeEvent("MiddleButtonReleaseEvent") def _on_mouse_wheel(self, Sender, Shift, WheelDelta, MousePos, Handled): x = MousePos.X y = MousePos.Y ctrl = 'ssCtrl' in Shift shift = 'ssShift' in Shift self._render_interactor.SetEventInformationFlipY(x, y, ctrl, shift, chr(0), 0, None) if WheelDelta > 0: self._render_interactor.MouseWheelForwardEvent() else: self._render_interactor.MouseWheelBackwardEvent() Handled.Value = True def _on_resize(self, Sender): width = Sender.ClientWidth height = Sender.ClientHeight if self._render_window: self._render_window.SetSize(width, height) self._render_interactor.ConfigureEvent() self.Repaint() def _on_paint(self, Sender): pass if not self._render_interactor is None: self._render_interactor.Render() # == BEG: xxx # def GetRenderWindow(self): if self._render_window is None: # create render window and assign handle of this component hwnd = self.Handle self._render_window = vtkRenderWindow() self._render_window.SetWindowInfo(str(int(hwnd))) # create render interactor as generic render window interactor self._render_interactor = vtkGenericRenderWindowInteractor() self._render_interactor.SetRenderWindow(self._render_window) # add render interactor timer events to the observer self._render_interactor.AddObserver('CreateTimerEvent', self.CreateTimer) self._render_interactor.AddObserver('DestroyTimerEvent', self.DestroyTimer) return self._render_window def Render(self): self.update() def CreateTimer(self, obj, evt): if self._render_interactor_timer is None: self._render_interactor_timer = Timer(self) self._render_interactor_timer.Enabled = False self._render_interactor_timer.Interval = 10 self._render_interactor_timer.OnTimer = self.TimerEvent self._render_interactor_timer.Enabled = True def DestroyTimer(self, obj, evt): self._render_interactor_timer.Enabled = False return 1 def TimerEvent(self, Sender): if not self._render_interactor is None: self._render_interactor.TimerEvent() # # == END: xxx def vclVTKRenderWindowInteractorConeExample(): """A simple example that uses the vclVTKRenderWindowInteractor class.""" from vtkmodules.vtkFiltersSources import vtkConeSource from vtkmodules.vtkRenderingCore import vtkActor, vtkPolyDataMapper, vtkRenderer import vtkmodules.vtkRenderingOpenGL2 import vtkmodules.vtkInteractionStyle class MainView(Form): def __init__(self, owner): super().__init__(owner) self.vtk_panel = vclVTKRenderWindowInteractor(self) self.vtk_panel.Parent = self self.vtk_panel.Align = 'alClient' self.vtk_panel.AlignWithMargins = True # set default control values self.DoubleBuffered = True # set main form events handlers self.OnClose = self.__on_form_close def __on_form_close(self, sender, action): if sender is None: return if sender == self: action.Value = caFree # initialize application Application.Initialize() Application.Title = "" # create and show view view = MainView(Application) try: def on_timer(Sender): coneActor.RotateX(5) coneActor.RotateY(2.5) coneActor.RotateY(1) widget.GetRenderWindow().Render() timer.interval = 100 view.Show() widget = view.vtk_panel ren = vtkRenderer() widget.GetRenderWindow().AddRenderer(ren) cone = vtkConeSource() cone.SetResolution(8) coneMapper = vtkPolyDataMapper() coneMapper.SetInputConnection(cone.GetOutputPort()) coneActor = vtkActor() coneActor.SetMapper(coneMapper) ren.AddActor(coneActor) # initialize and start render interactor widget.Initialize() widget.Start() timer = Timer(None) timer.Interval = 1000 timer.OnTimer = on_timer FreeConsole() Application.Run() finally: view.Destroy() if __name__ == '__main__': vclVTKRenderWindowInteractorConeExample() Final result: Unfortunately VTKPanel will be available only with a custom DelphiVCL Python. Will be interesting to have a native control which does same behaviour aka ExternControl or similar name to manage Python objects can work with a windowed delphivcl control using window handle.
  13. shineworld

    Delphi + Python

    Do not miss to add OnClose event in the main form and evaluate action for caFree class DesktopView(Form): def __init__(self, owner): # call vcl inherited view constructor super().__init__(owner) ... # set main form events handlers self.OnClose = self.__on_form_close ... def __on_form_close(self, sender, action): if sender is None: return if sender == self: action.Value = caFree ... def main(): # initialize application Application.Initialize() Application.Title = "" # create and show main_view main_view = DesktopView(Application) try: main_view.Show() FreeConsole() Application.Run() finally: main_view.Destroy() # main entry point if __name__ == "__main__": main()
  14. shineworld

    VTK in DelphiVCL or DelphiFMX

    A few small steps forward... Now VTK is displaying quite well but putrously I still haven't quite figured out if CustomControl is the right "hook" point for VTK. VTK requires docking to a control with Handle. But I assume Paint's native handling of the control should come disabled. Also, CustomControl (TCustomControl) lacks OnMouseXXX events to capture events to send to VTK's iterator. Perhaps the only solution is to add a control derived from TWindowControl to DelphiVCL that would accommodate what VTK requires for integration. In the video the comparison of the same code in DelphiVCL and PySide6 (QT), which I want to get rid of as soon as possible.
  15. shineworld

    VTK in DelphiVCL or DelphiFMX

    The code is a real crap, I'm just trying the right way to get the thing working, but Python + DelphiVCL + VTK looks like it could go. from delphivcl import * from vtkmodules.vtkRenderingCore import vtkRenderWindow from vtkmodules.vtkRenderingUI import vtkGenericRenderWindowInteractor BASE_CLASS_NAME = WinControl class vclVTKRenderWindowInteractor(BASE_CLASS_NAME): def __init__(self, owner): BASE_CLASS_NAME.__init__(self, owner) self._RenderWindow = None self._Iren = None def __getattr__(self, attr): """Makes the object behave like a vtkGenericRenderWindowInteractor""" if attr == '__vtk__': return lambda t=self._Iren: t elif hasattr(self._Iren, attr): return getattr(self._Iren, attr) else: raise AttributeError(self.__class__.__name__ + " has no attribute named " + attr) def GetRenderWindow(self): if self._RenderWindow is None: hwnd = self.Handle self._RenderWindow = vtkRenderWindow() self._RenderWindow.SetWindowInfo(str(int(hwnd))) self._Iren = vtkGenericRenderWindowInteractor() self._Iren.SetRenderWindow(self._RenderWindow) return self._RenderWindow def Render(self): self.update() def vclVTKRenderWindowInteractorConeExample(): """A simple example that uses the vclVTKRenderWindowInteractor class.""" from vtkmodules.vtkFiltersSources import vtkConeSource from vtkmodules.vtkRenderingCore import vtkActor, vtkPolyDataMapper, vtkRenderer import vtkmodules.vtkRenderingOpenGL2 import vtkmodules.vtkInteractionStyle class MainView(Form): def __init__(self, owner): self.vtk_panel = vclVTKRenderWindowInteractor(self) self.vtk_panel.Parent = self self.vtk_panel.Align = 'alClient' self.vtk_panel.AlignWithMargins = True self.vtk_panel.BevelInner = 'bvNone' self.vtk_panel.BevelKind = 'bkFlat' self.vtk_panel.BevelOuter = 'bvNone' self.vtk_panel.Color = clCream self.vtk_panel.ParentBackground = False self.vtk_panel.Caption = 'Hello World!' # set main form events handlers self.OnClose = self.__on_form_close def __on_form_close(self, sender, action): if sender is None: return if sender == self: action.Value = caFree # initialize application Application.Initialize() Application.Title = "" # create and show view view = MainView(Application) try: def on_timer(Sender): coneActor.RotateX(10) coneActor.RotateY(5) coneActor.RotateY(2.5) widget.GetRenderWindow().Render() timer.interval = 100 view.Show() widget = view.vtk_panel ren = vtkRenderer() widget.GetRenderWindow().AddRenderer(ren) cone = vtkConeSource() cone.SetResolution(8) coneMapper = vtkPolyDataMapper() coneMapper.SetInputConnection(cone.GetOutputPort()) coneActor = vtkActor() coneActor.SetMapper(coneMapper) ren.AddActor(coneActor) widget._Iren.Initialize() # Initialize the interactor widget._Iren.Start() # Start the interactor timer = Timer(None) timer.Interval = 1000 timer.OnTimer = on_timer FreeConsole() Application.Run() finally: view.Destroy() if __name__ == '__main__': vclVTKRenderWindowInteractorConeExample()
×