修改插入GTK TextBuffer的文本

时间:2014-07-19 07:22:25

标签: haskell gtk gtk3

我有一个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

1 个答案:

答案 0 :(得分:2)

首先,让我们从TextBuffer获取TextView

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"