












lazarus 4.8及之前的版本QT5中文输入多字词组时只输入前2个中文,lazarus trunk的QT5已修复这个Bug.
lazarus 4.8版可以参考lazarus trunk的版处理就可以。
lazarus/lcl/interfaces/qt5/qtwidgets.pas单元的
function TQtWidget.SlotInputMethod(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
负责QT5文字输入。
function TQtWidget.SlotInputMethod(Sender: QObjectH; Event: QEventH): Boolean; cdecl; var InputEvent: QInputMethodEventH; WStr: WideString; UnicodeChar: Cardinal; UnicodeOutLen: integer; KeyEvent: QKeyEventH; s:TStringList; begin Result := True; if not (QEvent_type(Event) = QEventInputMethod) then Exit; {$ifdef VerboseQt} DebugLn('TQtWidget.SlotInputMethod ', dbgsname(LCLObject)); {$endif} InputEvent := QInputMethodEventH(Event); QInputMethodEvent_commitString(InputEvent, @WStr); s:=TStringList.Create; s.Add(WStr); s.SaveToFile('/home/lbz/111.txt'); UnicodeChar := UTF8CodepointToUnicode(PChar(WStr), UnicodeOutLen); {$IFDEF VerboseQtKeys} writeln('> TQtWidget.SlotInputMethod ',dbgsname(LCLObject),' event=QEventInputMethod:'); writeln(' commmitString ',WStr,' len ',length(WStr),' UnicodeChar ',UnicodeChar, ' UnicodeLen ',UnicodeOutLen); writeln(' sending QEventKeyPress'); {$ENDIF} KeyEvent := QKeyEvent_create(QEventKeyPress, PtrInt(UnicodeChar), QGUIApplication_keyboardModifiers, @WStr, False, 1); try // do not send it to queue, just pass it to SlotKey Result := SlotKey(Sender, KeyEvent); finally QKeyEvent_destroy(KeyEvent); end; {$IFDEF VerboseQtKeys} writeln('< TQtWidget.SlotInputMethod End: ',dbgsname(LCLObject),' event=QEventInputMethod, sent QEventKeyPress'); {$ENDIF} end;
修复方法:
打开lazarus/lcl/interfaces/qt5/qtwidgets.pas
添加3个变量(红色3行):
TQtWidget = class(TQtObject, IUnknown) private FDefaultFocusReason: QtFocusReason; FInResizeEvent: boolean; FWidgetState: TQtWidgetStates; FWidgetDefaultFont: TQtFont; FWidgetLCLFont: TQtFont; FWidgetNeedFontColorInitialization: Boolean; FChildOfComplexWidget: TChildOfComplexWidget; FOwnWidget: Boolean; FProps: TStringList; FPaintData: TPaintData; FCentralWidget: QWidgetH; FContext: HDC; FParams: TCreateParams; FDefaultCursor: QCursorH; FKeysToEat: TByteSet; FText: WideString; FHasCaret: Boolean; FLastCaretPos: TQtPoint; FHasPaint: Boolean; FOwner: TQtWidget; FWidgetColorRole: QPaletteColorRole; FTextColorRole: QPaletteColorRole; FPalette: TQtWidgetPalette; { Input Method } FPreEditStr: WideString; FCommitStr: WideString; FIMPreedit: Boolean;
找到
function TQtWidget.SlotInputMethod(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
复制以下代码替换原有的SlotInputMethod
function TQtWidget.SlotInputMethod(Sender: QObjectH; Event: QEventH): Boolean; cdecl; var InputEvent: QInputMethodEventH; WStr, temps: WideString; UnicodeChar: Cardinal; i: integer; KeyEvent: QKeyEventH; Msg: TLMessage; begin Result := False; if not (QEvent_type(Event) = QEventInputMethod) then Exit; {$ifdef VerboseQt} DebugLn('TQtWidget.SlotInputMethod ', dbgsname(LCLObject)); {$endif} InputEvent := QInputMethodEventH(Event); FPreEditStr:=''; FCommitStr:=''; QInputMethodEvent_commitString(InputEvent, @FCommitStr); QInputMethodEvent_preeditString(InputEvent, @FPreEditStr); WStr:=FCommitStr; { commit } if FCommitStr<>'' then begin if CanSendLCLMessage then begin Msg.Msg:=LM_IM_COMPOSITION; Msg.WParam:=GTK_IM_FLAG_COMMIT or GTK_IM_FLAG_END; Msg.LParam:=LPARAM(@FCommitStr); Result:=DeliverMessage(Msg)<>0; end; FIMPreedit:=False; end; { preedit } if CanSendLCLMessage then begin Msg.Msg:=LM_IM_COMPOSITION; Msg.WParam:=GTK_IM_FLAG_PREEDIT; if not FIMPreedit then Msg.WParam:=Msg.WParam or GTK_IM_FLAG_START else Msg.WParam:=Msg.WParam or GTK_IM_FLAG_REPLACE; Msg.LParam:=LPARAM(@FPreEditStr); { Don't update result } DeliverMessage(Msg); end; FIMPreedit:=FPreEditStr<>''; { commit to keyinput } if WStr<>'' then begin {$IFDEF VerboseQtKeys} writeln('> TQtWidget.SlotInputMethod ',dbgsname(LCLObject),' event=QEventInputMethod:'); writeln(' commmitString ',WStr,' len ',length(WStr),' UnicodeChar ',UnicodeChar) writeln(' sending QEventKeyPress'); {$ENDIF} for i:=1 to Length(WStr) do begin UnicodeChar := PWord(@WStr[i])^; temps:=WStr[i]; KeyEvent := QKeyEvent_create(QEventKeyPress, PtrInt(UnicodeChar), QGUIApplication_keyboardModifiers, @temps); try // do not send it to queue, just pass it to SlotKey Result := SlotKey(Sender, KeyEvent); finally QKeyEvent_destroy(KeyEvent); end; {$IFDEF VerboseQtKeys} writeln('< TQtWidget.SlotInputMethod End: ',dbgsname(LCLObject),' event=QEventInputMethod, sent QEventKeyPress'); {$ENDIF} end; end; end;
重构lazarus及重新编译应用就可以修复多字词组的输入。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。