当前位置: 首页 > news >正文

lazarus 4.8及之前的版本QT5中文输入多字词组时只输入前2个中文

lazarus 4.8及之前的版本QT5中文输入多字词组时只输入前2个中文

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;
varInputEvent: QInputMethodEventH;WStr: WideString;UnicodeChar: Cardinal;UnicodeOutLen: integer;KeyEvent: QKeyEventH;s:TStringList;
beginResult := 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 SlotKeyResult := SlotKey(Sender, KeyEvent);finallyQKeyEvent_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)privateFDefaultFocusReason: 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;
varInputEvent: QInputMethodEventH;WStr, temps: WideString;UnicodeChar: Cardinal;i: integer;KeyEvent: QKeyEventH;Msg: TLMessage;
beginResult := 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<>'' thenbeginif CanSendLCLMessage thenbeginMsg.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 thenbeginMsg.Msg:=LM_IM_COMPOSITION;Msg.WParam:=GTK_IM_FLAG_PREEDIT;if not FIMPreedit thenMsg.WParam:=Msg.WParam or GTK_IM_FLAG_STARTelseMsg.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<>'' thenbegin{$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) dobeginUnicodeChar := 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 SlotKeyResult := SlotKey(Sender, KeyEvent);finallyQKeyEvent_destroy(KeyEvent);end;{$IFDEF VerboseQtKeys}writeln('< TQtWidget.SlotInputMethod End: ',dbgsname(LCLObject),' event=QEventInputMethod, sent QEventKeyPress');{$ENDIF}end;end;
end;

重构lazarus及重新编译应用就可以修复多字词组的输入。