You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gambas3 Qt5 TextEdit设置RichText后光标跳末尾如何解决

Gambas3 Qt5 TextEdit 富文本编辑光标跳转问题修复

问题复现

在Gambas3中使用Qt5 TextEdit控件实现富文本彩色输入功能时,原有代码如下:

Dim cursorpos As Integer

  If Key.Code = Key.Left Or Key.Code = Key.Up Or Key.code = Key.Right Or Key.Code = Key.Down Or Key.Code = Key.Delete Or Key.Code = Key.Backspace Then
    
    cursorpos = TextEdit1.Pos ' 记录光标位置
    Print cursorpos
    
  Else 
    cursorpos = TextEdit1.Pos
    Print cursorpos
    TextEdit1.RichText = "<font color = \"#224444\">" & Replace(TextEdit1.Text, gb.NewLine, "<br>") & "</font>" ' 替换换行为<br>标签套字体颜色
    Print "setting : ", cursorpos ' 打印值正确
    TextEdit1.Pos = cursorpos ' 赋值不生效
    Print "got : ", TextEdit1.Pos ' 光标直接跳转到字符串末尾
  Endif

测试操作流程:

  1. 编辑器内输入两行测试文本:
This si a line
this is a second line
  1. 用方向键移动光标到第一行笔误位置,按两次退格删除错误内容si,该步骤操作正常
  2. 输入字符"i"时,预期光标停留在刚输入的"i"后方,实际直接跳转到整个文本的最末尾

问题原因

整体给RichText属性赋值时,控件会完全重建内部的富文本文档结构:

  • 拼接的<font>、<br>等HTML标签会占用富文本内部的字符计数,但这些标签不会显示在编辑区,之前记录的纯文本光标位置和富文本内部位置不匹配
  • 赋值RichText后控件需要时间完成文档渲染,立刻设置Pos属性的操作会被控件默认的“重建文档后光标移到末尾”的逻辑覆盖,所以赋值不生效

修复方案

推荐方案:不要全量重写RichText,用原生光标接口设置样式

从根源上避免全量重建文档,通过TextCursor接口直接给输入的内容设置颜色,不会触发光标跳转,性能也更好:

Public Sub TextEdit1_KeyPress()
  ' 方向键、删除类按键不需要额外处理,走默认逻辑即可
  If Key.Code = Key.Left Or Key.Code = Key.Up Or Key.Code = Key.Right Or Key.Code = Key.Down Or Key.Code = Key.Delete Or Key.Code = Key.BackSpace Then Return
  ' 拦截默认输入,手动插入字符并设置样式
  Stop Event
  Dim hCursor As TextCursor = TextEdit1.Cursor
  ' 插入当前按下的字符
  hCursor.Insert(Chr(Key.Text))
  ' 选中刚插入的单个字符
  hCursor.MoveStart(-1)
  ' 设置对应颜色 #224444
  hCursor.ForeColor = Color.RGB(34, 68, 68)
  ' 取消选中,光标移动到刚输入字符的后方
  hCursor.MoveEnd()
End

兼容方案(不推荐):延迟设置光标+计算标签偏移

如果必须保留全量赋值RichText的逻辑,需要等控件完成文档渲染后,加上HTML标签的固定偏移量再设置光标位置,需要额外加一个短延迟定时器:

Dim cursorpos As Integer
' 提前计算前置标签的固定长度:<font color = "#224444"> 共24个字符
Const TAG_OFFSET As Integer = 24

Public Sub TextEdit1_KeyPress()
  If Key.Code = Key.Left Or Key.Code = Key.Up Or Key.code = Key.Right Or Key.Code = Key.Down Or Key.Code = Key.Delete Or Key.Code = Key.Backspace Then
    cursorpos = TextEdit1.Pos
  Else 
    cursorpos = TextEdit1.Pos
    TextEdit1.RichText = "<font color = \"#224444\">" & Replace(TextEdit1.Text, gb.NewLine, "<br>") & "</font>"
    ' 启动10ms延迟定时器,等文档渲染完成后再恢复光标
    tmrRestorePos.Delay = 10
    tmrRestorePos.Start
  Endif
End

Public Sub tmrRestorePos_Timer()
  ' 原光标位置加上前置标签的偏移量,才是富文本文档里的正确位置
  TextEdit1.Pos = cursorpos + TAG_OFFSET
  tmrRestorePos.Stop
End

内容的提问来源于stack exchange,提问作者Sean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 15:18:15