如何从 WxPython 读取内联样式

How to read inline-styles from WxPython

我正在尝试将文本放入 RichTextCtrl 中,然后在用户进行编辑后,我想将编辑后的文本与样式一起取回。这是我遇到麻烦的第二部分。在所有从缓冲区中获取样式的方法中,none 确实是用户友好的。

我想出的最好办法是使用 GetStyleForRange(range, style) 一次一个字符地遍历文本。 got 是一种更好的方法!现在这是我的代码,它逐步收集文本段和样式列表。

请给我一个更好的方法来做到这一点。我必须遗漏一些东西。

        buffer: wx.richtext.RichTextBuffer = self.rtc.GetBuffer()
        end = len(buffer.GetText())

        # Variables for text/style reading loop
        ch: str
        curStyle: str
        i: int = 0
        style = wx.richtext.RichTextAttr()
        text: List[str] = []
        textItems: List[Tuple[str, str]] = []

        # Read the style of the first character
        self.rtc.GetStyleForRange(wx.richtext.RichTextRange(i, i + 1), style)
        curStyle = self.describeStyle(style)

        # Loop until we hit the end. Use a while loop so we can control the index increment.
        while i < end + 1:
            # Read the current character and its style as `ch` and `newStyle`
            ch = buffer.GetTextForRange(wx.richtext.RichTextRange(i, i))
            self.rtc.GetStyleForRange(wx.richtext.RichTextRange(i, i + 1), style)
            newStyle = self.describeStyle(style)

            # If the style has changed, we flush the collected text and start new collection
            if text and newStyle != curStyle and ch != '\n':
                newText = "".join(text)
                textItems.append((newText, curStyle))
                text = []
                self.rtc.GetStyleForRange(wx.richtext.RichTextRange(i + 1, i + 2), style)
                curStyle = self.describeStyle(style)

            # Otherwise, collect the character and continue
            else:
                i += 1
                text.append(ch)

        # Capture the last text being collected
        newText = "".join(text)
        textItems.append((newText, newStyle))

这是我在上面评论中提到的解决方案的 C++ 版本。这是一个使用队列的简单树遍历,所以我认为应该可以轻松翻译成 python。

const wxRichTextBuffer& buffer = m_richText1->GetBuffer();
std::deque<const wxRichTextObject*> objects;
objects.push_front(&buffer);

while ( !objects.empty() )
{
    const wxRichTextObject* curObject = objects.front();
    objects.pop_front();

    if ( !curObject->IsComposite() )
    {
        wxRichTextRange range = curObject->GetRange();
        const wxRichTextAttr& attr = curObject->GetAttributes();

        // Do something with range and attr here.
    }
    else
    {
        // This is a composite object. Add its children to the queue.
        // The children are added in reverse order to do a depth first walk.
        const wxRichTextCompositeObject* curComposite =
            static_cast<const wxRichTextCompositeObject*>(curObject);

        size_t childCount = curComposite->GetChildCount() ;

        for ( int i = childCount - 1 ; i >= 0 ; --i )
        {
            objects.push_front(curComposite->GetChild(i));
        }
    }
}