【问题标题】:Modify text being inserted into GTK TextBuffer修改插入到 GTK TextBuffer 中的文本
【发布时间】:2014-07-19 07:22:25
【问题描述】:

我有一个TextView,我想自动将所有键入、粘贴等的文本转换为大写,可以吗?我尝试添加一个bufferInsertText 处理程序并自己从那里插入文本,但此错误消息不断弹出:

Gtk-WARNING **: Invalid text buffer iterator: either the iterator
is uninitialized, or the characters/pixbufs/widgets in the buffer
have been modified since the iterator was created.
You must use marks, character numbers, or line numbers to preserve
a position across buffer modifications.
You can apply tags and insert marks without invalidating your
iterators, but any mutation that affects 'indexable' buffer contents
(contents that can be referred to by character offset) will
invalidate all outstanding iterators

【问题讨论】:

    标签: haskell gtk gtk3


    【解决方案1】:

    首先,让我们从TextView 获取TextBuffer

    buffer ← G.get textView textViewBuffer
    

    现在,使用IORef,我们可以获得我们将要连接的bufferInsertText 信号的ID,因为我们稍后会需要它:

    sigInsertIdRef ← newIORef undefined
    sigInsertId ← buffer `on` bufferInsertText $ 
                    handler buffer sigInsertIdRef
    writeIORef sigInsertIdRef sigInsertId
    

    文本的实际插入发生在 TextBuffer 的默认处理程序中,该处理程序在我们的处理程序之后触发。因此,这就是我们应该在处理程序中做的事情:

    • 暂时禁用自定义处理程序(我们可以使用它的ConnectId 来实现)。
    • 请求缓冲区插入我们修改后的文本,现在将直接进入默认处理程序。
    • 再次启用自定义处理程序。
    • 阻止原始信号进一步进入链并触发默认处理程序。

    下面的代码正是这样做的:

    handler :: TextBuffer → IORef → TextIter → String → IO ()
    handler buffer sigIdRef iter str = do
      sigId ← readIORef sigIdRef
      signalBlock sigId
      textBufferInsert buffer iter (map toUpper str)
      signalUnblock sigId
      signalStopEmission buffer "insert-text"
    

    【讨论】:

      猜你喜欢
      • 2011-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多