Ok, something very strange is going on. I added a slot for the itemchanged signal that looks like this:
procedure TQtListWidget.SlotSelectionChange(current: QListWidgetItemH; previous: QListWidgetItemH); cdecl; var Msg: TLMessage; begin FillChar(Msg, SizeOf(Msg), #0); Msg.Msg := LM_SELCHANGE; try LCLObject.WindowProc(TLMessage(Msg)); except Application.HandleException(nil); end; end; If I comment out the LCLObject.WindowProc() line, no events are received for the listbox. If I don't commen it and click on the list box and drag to change selection, I will receive many OnClick and OnSelectionChange events. Could it be a problem with the qt bindings? It seams to me everything I did was correct. Here is my SetSlots function, I not only use a events look, but alse set a slot for a signal directly, because that signal has no corresponding event: class procedure TQtWSCustomListBox.SetSlots(const QtListWidget: TQtListWidget); var Method: TMethod; Hook : QListWidget_hookH; begin // Various Events Hook := QListWidget_hook_create(QtListWidget.Widget); TEventFilterMethod(Method) := QtListWidget.EventFilter; QObject_hook_hook_events(Hook, Method); // OnSelectionChange event QListWidget_currentItemChanged_Event(Method) := QtListWidget.SlotSelectionChange; QListWidget_hook_hook_currentItemChanged(Hook, Method); end; I also attached a diff. -- Felipe Monteiro de Carvalho
Index: lcl/interfaces/qt/qtobjects.pas =================================================================== --- lcl/interfaces/qt/qtobjects.pas (revisão 9941) +++ lcl/interfaces/qt/qtobjects.pas (cópia de trabalho) @@ -37,7 +37,6 @@ public //property Sorted: boolean read FSorted write SetSorted; property Owner: TWinControl read FOwner; - function ListChangedHandler(Sender: QObjectH; Event: QEventH): Boolean; cdecl; end; { TQtMemoStrings } @@ -91,7 +90,141 @@ uses qtprivate, LMessages; +{ TQtListStrings } + +procedure TQtListStrings.InternalUpdate; +begin + +end; + +procedure TQtListStrings.ExternalUpdate(var Astr: TStringList; Clear: Boolean); +var + i: Integer; +begin + FUpdating := True; + if Clear then + QListWidget_clear(FQtListWidget); + for i := 0 to AStr.Count -1 do + QListWidget_additem(FQtListWidget, @WideString(Astr[i])); + FUpdating := False; + IsChanged; + FUpdating := False; +end; + +procedure TQtListStrings.IsChanged; +begin + +end; + +function TQtListStrings.GetTextStr: string; +begin + Result := inherited GetTextStr; +end; + +function TQtListStrings.GetCount: integer; +begin + if FListChanged then InternalUpdate; + Result := FStringList.Count; +end; + +function TQtListStrings.Get(Index: Integer): string; +begin + if FListChanged then InternalUpdate; + if Index < FStringList.Count then + Result := FStringList.Strings[Index] + else Result := ''; +end; + {------------------------------------------------------------------------------ + Method: TQtListStrings.Create + Params: Qt Widget Handle and Lazarus WinControl Parent Object + Returns: Nothing + + Contructor for the class. + ------------------------------------------------------------------------------} +constructor TQtListStrings.Create(ListWidgetH: QListWidgetH; TheOwner: TWinControl); +var + Method: TMethod; + Hook : QListWidget_hookH; +// Astr: WideString; + i: Integer; +begin + inherited Create; + + {$ifdef VerboseQt} + if (ListWidgetH = nil) then WriteLn('TQtMemoStrings.Create Unspecified ListWidgetH widget'); + if (TheOwner = nil) then WriteLn('TQtMemoStrings.Create Unspecified owner'); + {$endif} + + FStringList := TStringList.Create; + FQtListWidget := ListWidgetH; + FStringList.Text := TCustomListBox(TheOwner).Items.Text; + FOwner:=TheOwner; +end; + +destructor TQtListStrings.Destroy; +begin + inherited Destroy; +end; + +procedure TQtListStrings.Assign(Source: TPersistent); +begin + inherited Assign(Source); +end; + +procedure TQtListStrings.Clear; +begin + FUpdating := True; + FStringList.Clear; + QListWidget_clear(FQtListWidget); + FListChanged := False; + FUpdating := False; + IsChanged; +end; + +procedure TQtListStrings.Delete(Index: integer); +{var + Astr: WideString;} +begin + if FListChanged then InternalUpdate; + + if Index < FStringList.Count then + begin + FStringList.Delete(Index); +// Astr := FStringList.Text; + ExternalUpdate(FStringList,True); + FListChanged := False; + end; + +(* FStringList.Delete(Index); + QListWidget_takeitem(FQtListWidget, Index); *) +end; + +procedure TQtListStrings.Insert(Index: integer; const S: string); +{var + Astr: WideString;} +begin + if FListChanged then InternalUpdate; + + if Index < 0 then Index := 0; + + if Index <= FStringList.Count then + begin + FStringList.Insert(Index,S); +// Astr := FStringList.Text; + ExternalUpdate(FStringList,True); + FListChanged := False; + end; +end; + +procedure TQtListStrings.SetText(TheText: PChar); +begin + inherited SetText(TheText); +end; + +{ TQtMemoStrings } + +{------------------------------------------------------------------------------ Private Method: TQtMemoStrings.InternalUpdate Params: None Returns: Nothing @@ -139,10 +272,11 @@ ------------------------------------------------------------------------------} procedure TQtMemoStrings.IsChanged; begin - if Assigned((FOwner as TCustomMemo).OnChange) then begin + if Assigned((FOwner as TCustomMemo).OnChange) then + begin (FOwner as TCustomMemo).Modified := False; (FOwner as TCustomMemo).OnChange(self); - end; + end; end; {------------------------------------------------------------------------------ @@ -194,8 +328,7 @@ Contructor for the class. ------------------------------------------------------------------------------} -constructor TQtMemoStrings.Create(TextEdit: QTextEditH; - TheOwner: TWinControl); +constructor TQtMemoStrings.Create(TextEdit: QTextEditH; TheOwner: TWinControl); var Method: TMethod; Hook : QTextEdit_hookH; @@ -213,11 +346,12 @@ QTextEdit_toPlainText(TextEdit,@Astr); // get the memo content FStringList.Text := Astr; FOwner:=TheOwner; + // Callback Event {Method := MemoChanged;} TEventFilterMethod(Method) := TextChangedHandler; Hook := QTextEdit_hook_create(FQtTextEdit); - QTextEdit_hook_hook_textChanged(Hook,Method); + QTextEdit_hook_hook_textChanged(Hook, Method); end; {------------------------------------------------------------------------------ @@ -433,138 +567,5 @@ Result := QImage_numBytes(Handle); end; -{ TQtListStrings } - -procedure TQtListStrings.InternalUpdate; -begin - -end; - -procedure TQtListStrings.ExternalUpdate(var Astr: TStringList; Clear: Boolean); -var - i: Integer; -begin - FUpdating := True; - if Clear then - QListWidget_clear(FQtListWidget); - for i := 0 to AStr.Count -1 do - QListWidget_additem(FQtListWidget, @WideString(Astr[i])); - FUpdating := False; - IsChanged; - FUpdating := False; -end; - -procedure TQtListStrings.IsChanged; -begin - -end; - -function TQtListStrings.GetTextStr: string; -begin - Result:=inherited GetTextStr; -end; - -function TQtListStrings.GetCount: integer; -begin - if FListChanged then InternalUpdate; - Result := FStringList.Count; -end; - -function TQtListStrings.Get(Index: Integer): string; -{var - QListWidgetItem: QListWidgetItemH;} -begin -{ QListWidgetItem := QListWidget_item(FQtListWidget, Index); - Result := QListWidgetItem;} - if FListChanged then InternalUpdate; - if Index < FStringList.Count then - Result := FStringList.Strings[Index] - else Result := ''; -end; - -constructor TQtListStrings.Create(ListWidgetH: QListWidgetH; - TheOwner: TWinControl); -var - Method: TMethod; - Hook : QListWidget_hookH; -// Astr: WideString; - i: Integer; -begin - inherited Create; - - FStringList := TStringList.Create; - FQtListWidget := ListWidgetH; - - for i := 0 to QListWidget_Count(ListWidgetH) - 1 do - FStringList.Add(TCustomListBox(TheOwner).Items.Strings[i]); - - FOwner:=TheOwner; - // Callback Event - {Method := ListChanged;} - TEventFilterMethod(Method) := ListChangedHandler; - Hook := QListWidget_hook_create(FQtListWidget); - QListWidget_hook_hook_itemChanged(Hook,Method); -end; - -destructor TQtListStrings.Destroy; -begin - inherited Destroy; -end; - -procedure TQtListStrings.Assign(Source: TPersistent); -begin - inherited Assign(Source); -end; - -procedure TQtListStrings.Clear; -begin - FUpdating := True; - FStringList.Clear; - QListWidget_clear(FQtListWidget); - FListChanged := False; - FUpdating := False; - IsChanged; -end; - -procedure TQtListStrings.Delete(Index: integer); -{var - Astr: WideString;} -begin - if FListChanged then InternalUpdate; - if Index < FStringList.Count then begin - FStringList.Delete(Index); -// Astr := FStringList.Text; - ExternalUpdate(FStringList,True); - FListChanged := False; - end; -(* FStringList.Delete(Index); - QListWidget_takeitem(FQtListWidget, Index); *) -end; - -procedure TQtListStrings.Insert(Index: integer; const S: string); -{var - Astr: WideString;} -begin - if FListChanged then InternalUpdate; - if Index < 0 then Index := 0; - if Index <= FStringList.Count then begin - FStringList.Insert(Index,S); -// Astr := FStringList.Text; - ExternalUpdate(FStringList,True); - FListChanged := False; - end; -end; - -procedure TQtListStrings.SetText(TheText: PChar); -begin - inherited SetText(TheText); -end; - -function TQtListStrings.ListChangedHandler(Sender: QObjectH; Event: QEventH - ): Boolean; cdecl; -begin - -end; - end. Index: lcl/interfaces/qt/qtwsbuttons.pp =================================================================== --- lcl/interfaces/qt/qtwsbuttons.pp (revisão 9941) +++ lcl/interfaces/qt/qtwsbuttons.pp (cópia de trabalho) @@ -146,15 +146,15 @@ class procedure TQtWSButton.SetSlots(const QtButton: TQtPushButton); var Method: TMethod; + Hook : QObject_hookH; begin - // Inherited Callbacks -// TQtWSWinControl.SetSlots(QtButton); + // Various Events - // OnClick Event - - QAbstractButton_clicked2_Event(Method) := QtButton.SlotClicked; + Hook := QObject_hook_create(QtButton.Widget); - QAbstractButton_hook_hook_clicked2(QAbstractButton_hook_create(QtButton.Widget), Method); + TEventFilterMethod(Method) := QtButton.EventFilter; + + QObject_hook_hook_events(Hook, Method); end; {------------------------------------------------------------------------------ Index: lcl/interfaces/qt/qtprivate.pp =================================================================== --- lcl/interfaces/qt/qtprivate.pp (revisão 9941) +++ lcl/interfaces/qt/qtprivate.pp (cópia de trabalho) @@ -52,6 +52,7 @@ procedure SlotFocus(FocusIn: Boolean); cdecl; procedure SlotKey(Event: QEventH); cdecl; procedure SlotMouse(Event: QEventH); cdecl; + procedure SlotMouseMove(Event: QEventH); cdecl; procedure SlotPaint(Event: QEventH); cdecl; procedure SlotResize; cdecl; public @@ -286,12 +287,16 @@ end; + { TQtListWidget } + TQtListWidget = class(TQtListView) private public constructor Create(const AWinControl: TWinControl; const AParams: TCreateParams); override; destructor Destroy; override; public + procedure SlotSelectionChange(current: QListWidgetItemH; previous: QListWidgetItemH); cdecl; + public function currentRow: Integer; procedure setCurrentRow(row: Integer); end; @@ -366,7 +371,7 @@ QEventMouseButtonPress: SlotMouse(Event); QEventMouseButtonRelease: SlotMouse(Event); QEventMouseButtonDblClick: SlotMouse(Event); - QEventMouseMove: SlotMouse(Event); + QEventMouseMove: SlotMouseMove(Event); QEventResize: SlotResize; QEventPaint: SlotPaint(Event); @@ -489,11 +494,39 @@ Returns: Nothing ------------------------------------------------------------------------------} procedure TQtWidget.SlotMouse(Event: QEventH); cdecl; +var + Msg: TLMMouse; begin + FillChar(Msg, SizeOf(Msg), #0); + + case QEvent_type(Event) of + QEventMouseButtonPress: Msg.Msg := LM_CLICKED; + QEventMouseButtonRelease: Msg.Msg := LM_RELEASED; + QEventMouseButtonDblClick: Msg.Msg := LM_CLICKED; + else + Msg.Msg := LM_CLICKED; + end; + try + LCLObject.WindowProc(TLMessage(Msg)); + except + Application.HandleException(nil); + end; end; {------------------------------------------------------------------------------ + Function: TQtWidget.SlotMouseMove + Params: None + Returns: Nothing + ------------------------------------------------------------------------------} +procedure TQtWidget.SlotMouseMove(Event: QEventH); cdecl; +var + Msg: TLMMouseMove; +begin + FillChar(Msg, SizeOf(Msg), #0); +end; + +{------------------------------------------------------------------------------ Function: TQtWidget.SlotPaint Params: None Returns: Nothing @@ -1382,7 +1415,6 @@ QMainWindow_setCentralWidget(Window, Widget); // Accepts keyboard and mouse events - QWidget_setFocusPolicy(Window, QtStrongFocus); QWidget_setFocusPolicy(Widget, QtStrongFocus);} end; @@ -2188,6 +2220,27 @@ end; {------------------------------------------------------------------------------ + Function: TQtListWidget.SlotSelectionChange + Params: None + Returns: Nothing + ------------------------------------------------------------------------------} +procedure TQtListWidget.SlotSelectionChange(current: QListWidgetItemH; + previous: QListWidgetItemH); cdecl; +var + Msg: TLMessage; +begin + FillChar(Msg, SizeOf(Msg), #0); + + Msg.Msg := LM_SELCHANGE; + + try + LCLObject.WindowProc(TLMessage(Msg)); + except + Application.HandleException(nil); + end; +end; + +{------------------------------------------------------------------------------ Function: TQtListWidget.currentRow Params: None Returns: Nothing Index: lcl/interfaces/qt/qtwsstdctrls.pp =================================================================== --- lcl/interfaces/qt/qtwsstdctrls.pp (revisão 9941) +++ lcl/interfaces/qt/qtwsstdctrls.pp (cópia de trabalho) @@ -107,6 +107,7 @@ TQtWSCustomListBox = class(TWSCustomListBox) private + class procedure SetSlots(const QtListWidget: TQtListWidget); protected public class function CreateHandle(const AWinControl: TWinControl; @@ -307,6 +308,31 @@ { TQtWSCustomListBox } {------------------------------------------------------------------------------ + Method: TQtWSCustomListBox.SetSlots + Params: None + Returns: Nothing + ------------------------------------------------------------------------------} +class procedure TQtWSCustomListBox.SetSlots(const QtListWidget: TQtListWidget); +var + Method: TMethod; + Hook : QListWidget_hookH; +begin + // Various Events + + Hook := QListWidget_hook_create(QtListWidget.Widget); + + TEventFilterMethod(Method) := QtListWidget.EventFilter; + + QObject_hook_hook_events(Hook, Method); + + // OnSelectionChange event + + QListWidget_currentItemChanged_Event(Method) := QtListWidget.SlotSelectionChange; + + QListWidget_hook_hook_currentItemChanged(Hook, Method); +end; + +{------------------------------------------------------------------------------ Method: TQtWSCustomListBox.CreateHandle Params: None Returns: Nothing @@ -316,6 +342,9 @@ QtListWidget: TQtListWidget; begin QtListWidget := TQtListWidGet.Create(AWinControl, AParams); + + SetSlots(QtListWidget); + Result := THandle(QtListWidget); end;