View Issue Details

IDProjectCategoryView StatusLast Update
0029343LazarusWidgetsetpublic2016-01-16 13:15
ReporterBart BroersmaAssigned ToBart Broersma 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Platformi386OSLinuxOS VersionFedora Core 18
Product Version1.7 (SVN)Product Build 
Target VersionFixed in Version1.6 
Summary0029343: TFloatSpinEdit on Linux QT does not fire OnChange when Text is changed (unless Value is changed by it)
DescriptionOn Windows and GTK2 TFloatSpinEdit fires OnChange whenevr the Text is changed.
This is as it should be, since the control derives from TCustomEdit.
On QT however, OnChange is only fired when altering the Text also alters the Value:
Change text from 50.0 to 50: no OnChange fires.
Change text from 50 yo 5: OnChange fires.
Steps To ReproduceUnzip attached sample project.
Set buildmode to QT
Buid and run

Set cursor at end of text, press BackSpace until there is only one digit ("5") left.
Expected behaviour:
OnChange: Value = 50.00, Text = "50.0"
OnChange: Value = 50.00, Text = "50."
OnChange: Value = 50.00, Text = "50"
OnChange: Value = 5.00, Text = "5"

Observed behaviour:
Only one OnChange is fired:
OnChange: Value = 5.00, Text = "5"
TagsNo tags attached.
Fixed in Revisionr51302
LazTarget1.6
WidgetsetQT
Attached Files
  • spintest.zip (67,831 bytes)
  • qtspinbox_textchanged.diff (2,633 bytes)
    Index: lcl/interfaces/qt/qtwidgets.pas
    ===================================================================
    --- lcl/interfaces/qt/qtwidgets.pas	(revision 51207)
    +++ lcl/interfaces/qt/qtwidgets.pas	(working copy)
    @@ -1066,6 +1066,7 @@
         {$ENDIF}
         FEditingFinishedHook: QAbstractSpinBox_hookH;
         FLineEditHook: QObject_hookH;
    +    FTextChangedHook: QLineEdit_hookH;
         // parts
         FLineEdit: QLineEditH;
         function GetLineEdit: QLineEditH;
    @@ -1082,6 +1083,7 @@
         procedure setMaxLength(const ALength: Integer);
         procedure setSelection(const AStart, ALength: Integer);
         procedure setCursorPosition(const ACursorPosition: Integer);
    +    procedure SignalLineEditTextChanged(AnonParam1: PWideString); virtual; cdecl;
         procedure Cut;
         procedure Copy;
         procedure Paste;
    @@ -10923,6 +10925,8 @@
       begin
         FLineEditHook := QObject_hook_create(FLineEdit);
         QObject_hook_hook_events(FLineEditHook, @LineEditEventFilter);
    +    FTextChangedHook := QLineEdit_hook_create(FLineEdit);
    +    QLineEdit_hook_hook_textChanged(FTextChangedHook, @SignalLineEditTextChanged);
       end;
       Result := FLineEdit;
     end;
    @@ -10936,6 +10940,16 @@
         Result := EventFilter(QWidgetH(Sender), Event);
     end;
     
    +procedure TQtAbstractSpinBox.SignalLineEditTextChanged(AnonParam1: PWideString); cdecl;
    +var
    +  Msg: TLMessage;
    +begin
    +  FillChar(Msg{%H-}, SizeOf(Msg), #0);
    +  Msg.Msg := CM_TEXTCHANGED;
    +  if not InUpdate then
    +    DeliverMessage(Msg);
    +end;
    +
     function TQtAbstractSpinBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
     var
       Parent: QWidgetH;
    @@ -11134,6 +11148,12 @@
         QObject_hook_destroy(FLineEditHook);
         FLineEditHook := nil;
       end;
    +
    +  if FTextChangedHook <> nil then
    +  begin
    +    QLineEdit_hook_destroy(FTextChangedHook);
    +    FTextChangedHook := nil;
    +  end;
       
       inherited DetachEvents;
     end;
    @@ -11261,14 +11281,16 @@
     end;
     
     procedure TQtFloatSpinBox.SignalValueChanged(p1: Double); cdecl;
    -var
    -  Msg: TLMessage;
    +// var
    +//  Msg: TLMessage;
     begin
       FValue := p1;
    +  (*
       FillChar(Msg{%H-}, SizeOf(Msg), #0);
       Msg.Msg := CM_TEXTCHANGED;
       if not InUpdate then
         DeliverMessage(Msg);
    +  *)
     end;
     
     { TQtSpinBox }
    @@ -11336,14 +11358,14 @@
     end;
     
     procedure TQtSpinBox.SignalValueChanged(p1: Integer); cdecl;
    -var
    -  Msg: TLMessage;
    +// var
    +//  Msg: TLMessage;
     begin
       FValue := p1;
    -  FillChar(Msg{%H-}, SizeOf(Msg), #0);
    -  Msg.Msg := CM_TEXTCHANGED;
    -  if not InUpdate then
    -    DeliverMessage(Msg);
    +  // FillChar(Msg{%H-}, SizeOf(Msg), #0);
    +  // Msg.Msg := CM_TEXTCHANGED;
    +  // if not InUpdate then
    +  //  DeliverMessage(Msg);
     end;
     
     { TQtListView }
    

Activities

Bart Broersma

2016-01-05 19:23

developer  

spintest.zip (67,831 bytes)

Zeljan Rikalo

2016-01-05 20:59

developer   ~0088665

Note for me:There's already hook to get private QLineEditH of QAbstractSpinBox , adding textChanged to QLineEditH of QAbstractSpinBox will provide all text changed events.

Zeljan Rikalo

2016-01-05 21:07

developer  

qtspinbox_textchanged.diff (2,633 bytes)
Index: lcl/interfaces/qt/qtwidgets.pas
===================================================================
--- lcl/interfaces/qt/qtwidgets.pas	(revision 51207)
+++ lcl/interfaces/qt/qtwidgets.pas	(working copy)
@@ -1066,6 +1066,7 @@
     {$ENDIF}
     FEditingFinishedHook: QAbstractSpinBox_hookH;
     FLineEditHook: QObject_hookH;
+    FTextChangedHook: QLineEdit_hookH;
     // parts
     FLineEdit: QLineEditH;
     function GetLineEdit: QLineEditH;
@@ -1082,6 +1083,7 @@
     procedure setMaxLength(const ALength: Integer);
     procedure setSelection(const AStart, ALength: Integer);
     procedure setCursorPosition(const ACursorPosition: Integer);
+    procedure SignalLineEditTextChanged(AnonParam1: PWideString); virtual; cdecl;
     procedure Cut;
     procedure Copy;
     procedure Paste;
@@ -10923,6 +10925,8 @@
   begin
     FLineEditHook := QObject_hook_create(FLineEdit);
     QObject_hook_hook_events(FLineEditHook, @LineEditEventFilter);
+    FTextChangedHook := QLineEdit_hook_create(FLineEdit);
+    QLineEdit_hook_hook_textChanged(FTextChangedHook, @SignalLineEditTextChanged);
   end;
   Result := FLineEdit;
 end;
@@ -10936,6 +10940,16 @@
     Result := EventFilter(QWidgetH(Sender), Event);
 end;
 
+procedure TQtAbstractSpinBox.SignalLineEditTextChanged(AnonParam1: PWideString); cdecl;
+var
+  Msg: TLMessage;
+begin
+  FillChar(Msg{%H-}, SizeOf(Msg), #0);
+  Msg.Msg := CM_TEXTCHANGED;
+  if not InUpdate then
+    DeliverMessage(Msg);
+end;
+
 function TQtAbstractSpinBox.CreateWidget(const AParams: TCreateParams): QWidgetH;
 var
   Parent: QWidgetH;
@@ -11134,6 +11148,12 @@
     QObject_hook_destroy(FLineEditHook);
     FLineEditHook := nil;
   end;
+
+  if FTextChangedHook <> nil then
+  begin
+    QLineEdit_hook_destroy(FTextChangedHook);
+    FTextChangedHook := nil;
+  end;
   
   inherited DetachEvents;
 end;
@@ -11261,14 +11281,16 @@
 end;
 
 procedure TQtFloatSpinBox.SignalValueChanged(p1: Double); cdecl;
-var
-  Msg: TLMessage;
+// var
+//  Msg: TLMessage;
 begin
   FValue := p1;
+  (*
   FillChar(Msg{%H-}, SizeOf(Msg), #0);
   Msg.Msg := CM_TEXTCHANGED;
   if not InUpdate then
     DeliverMessage(Msg);
+  *)
 end;
 
 { TQtSpinBox }
@@ -11336,14 +11358,14 @@
 end;
 
 procedure TQtSpinBox.SignalValueChanged(p1: Integer); cdecl;
-var
-  Msg: TLMessage;
+// var
+//  Msg: TLMessage;
 begin
   FValue := p1;
-  FillChar(Msg{%H-}, SizeOf(Msg), #0);
-  Msg.Msg := CM_TEXTCHANGED;
-  if not InUpdate then
-    DeliverMessage(Msg);
+  // FillChar(Msg{%H-}, SizeOf(Msg), #0);
+  // Msg.Msg := CM_TEXTCHANGED;
+  // if not InUpdate then
+  //  DeliverMessage(Msg);
 end;
 
 { TQtListView }

Zeljan Rikalo

2016-01-05 21:08

developer   ~0088667

@Bart, I've attached possible patch. Please test, and if it's ok on win and linux you can commit since I won't have time for heavy tests next days.
Pls, also clean commented code in SignalValueChanged() before commiting (if).

Bart Broersma

2016-01-06 12:08

developer   ~0088683

I can only test QT Linux (32 bit).
I'll report later.

Bart Broersma

2016-01-06 12:54

developer   ~0088687

Tested the patch.
Manually editing the text now fires OnChange.
However: setting value by code does not, nor does using the spinbuttons.
So, thats not good.

Re-enabling TQt(Float)SpinBox.SignalValueChanged will probably do, but then you can have multiple OnChanges for one change (which b.t.w. happens on GTK).
But IMO that would be preferrable over not having the OnChange at all.

Bart Broersma

2016-01-06 13:40

developer   ~0088689

Attached alternative patch.
In the hook for valuechanged it sets a flag, which then inhibits TextChanged to send the CM_TEXTCHANGED message.
A bit dirty, but it seems to work.

Please review.

Bart Broersma

2016-01-15 15:45

developer   ~0088911

@Zejan: seems I forgot to attach the patch.

Zeljan Rikalo

2016-01-16 11:27

developer   ~0088944

Bart, pls add commit to the merge list of 1.6 RC3

Bart Broersma

2016-01-16 13:15

developer   ~0088950

Already done.

Issue History

Date Modified Username Field Change
2016-01-05 19:23 Bart Broersma New Issue
2016-01-05 19:23 Bart Broersma File Added: spintest.zip
2016-01-05 20:10 Zeljan Rikalo Assigned To => Zeljan Rikalo
2016-01-05 20:10 Zeljan Rikalo Status new => assigned
2016-01-05 20:59 Zeljan Rikalo Note Added: 0088665
2016-01-05 21:07 Zeljan Rikalo File Added: qtspinbox_textchanged.diff
2016-01-05 21:08 Zeljan Rikalo Note Added: 0088667
2016-01-05 21:08 Zeljan Rikalo Status assigned => feedback
2016-01-06 12:08 Bart Broersma Note Added: 0088683
2016-01-06 12:08 Bart Broersma Status feedback => assigned
2016-01-06 12:54 Bart Broersma Note Added: 0088687
2016-01-06 13:40 Bart Broersma Note Added: 0088689
2016-01-15 15:45 Bart Broersma Fixed in Revision => r51302
2016-01-15 15:45 Bart Broersma LazTarget - => 1.6
2016-01-15 15:45 Bart Broersma Note Added: 0088911
2016-01-15 15:45 Bart Broersma Status assigned => resolved
2016-01-15 15:45 Bart Broersma Fixed in Version => 1.6
2016-01-15 15:45 Bart Broersma Resolution open => fixed
2016-01-15 15:45 Bart Broersma Assigned To Zeljan Rikalo => Bart Broersma
2016-01-16 11:27 Zeljan Rikalo Note Added: 0088944
2016-01-16 11:27 Zeljan Rikalo Status resolved => feedback
2016-01-16 11:27 Zeljan Rikalo Status feedback => resolved
2016-01-16 13:15 Bart Broersma Note Added: 0088950
2016-01-16 13:15 Bart Broersma Status resolved => closed