惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

有赞技术团队
有赞技术团队
Martin Fowler
Martin Fowler
N
Netflix TechBlog - Medium
WordPress大学
WordPress大学
罗磊的独立博客
H
Help Net Security
MongoDB | Blog
MongoDB | Blog
A
About on SuperTechFans
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
D
Docker
云风的 BLOG
云风的 BLOG
Microsoft Security Blog
Microsoft Security Blog
Blog — PlanetScale
Blog — PlanetScale
P
Proofpoint News Feed
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
I
InfoQ
J
Java Code Geeks
博客园 - 聂微东
大猫的无限游戏
大猫的无限游戏
Engineering at Meta
Engineering at Meta
美团技术团队
小众软件
小众软件
Stack Overflow Blog
Stack Overflow Blog
C
Check Point Blog

博客园 - 秋·风

修复lazarus datetimepicker控件在linux下拉不能选择日期的bug 用fpc trunk编译lazarus控件找不到TTimeZone 在银河麒麟v10操作系统应用程序执行遇到“权限不够”的提示 修复pl_cindy的Panel系列控件在gtk3出错的bug 龙芯 3A4000工具链的编译(mingw64) 修正lazarus在GTK3下的Synedit只能输入2个中文字符的Bug lazarus trunk linux从2026.07.02开始,LCLWidgetType默认使用gtk3,怎样改回gtk2 【aarch64-win64】DonAlfredo终于修复fpc将TSmallPoint赋值为一个负数,并将TSmallPoint赋值给TPoint时得到一个655xx的数值的bug lazarus编译时提示链接出错的处理方法 mORMot2两个BUG 【aarch64-win64】发现fpc aarch64-win64 将TSmallPoint赋值为一个负数,并赋值给TPoint时得到一个655xx的数值的bug 修复aarch64 win64下lazarus不弹出SourceTabPopUpMenu fpc aarch64-win64版编译应用时遇到一个奇怪的bug 在windows 11 on arm64系统编译lazarus出错的处理方法 修复TDBMemo只读不能使用Ctrl+C复制文字的Bug freepascal打补丁后已支持windows 11 on arm64(lazarus aarch64 windows版也可以运行了) 查看libc.so.6的版本号 Lazarus移动版启动程序 fpc 3.2.2交叉编译i386-linux链接出错 lazarus鸿蒙开发13:使用鸿蒙原生API画图--lazarus侧关键代码 lazarus鸿蒙开发12:使用鸿蒙原生API画图--鸿蒙侧关键代码 lazarus鸿蒙开发11:使用鸿蒙原生接口画图 lazarus鸿蒙开发10:lazarus一键编译、打包助手 lazarus鸿蒙开发9:使用命令行编译DevEco Studio应用 lazarus鸿蒙开发8:在DevEco Studio的日志窗口显示日志信息 lazarus鸿蒙开发7:在 Windows 上为 OpenHarmony (LoongArch64) 编译 Qt 5.15.12 SDK 指南 lazarus鸿蒙开发6:鸿蒙project配置 lazarus鸿蒙开发5:编译ohos_hap_project lazarus鸿蒙开发4:编译OHOS_QT_Lazarus lazarus鸿蒙开发3:编译libLazarusOHOS_Wrapper.so
lazarus 4.8及之前的版本QT5中文输入多字词组时只输入前2个中文
秋·风 · 2026-08-14 · via 博客园 - 秋·风

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及重新编译应用就可以修复多字词组的输入。