gpt4 book ai didi

c++ - QTextEdit 中的自定义文本(代码)区域

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:55:32 28 4
gpt4 key购买 nike

我有兴趣创建一个行为类似于代码区域的文本对象类型(继承 QTextObjectInterface):

  • 独特的背景
  • 边框
  • 等宽字体
  • 可编辑的内容
  • 实例需要可识别代码,以便可以提取其中的内容(将代码与周围内容分开)
  • 保存/加载(从常规 html 文件)
  • 语法高亮会是一个加分项,但不是必需的

文档的其他区域需要以通常的方式运行(字体属性可编辑、颜色可编辑等)。


Qt 提供an example用于使用 QTextEdit 实现自定义文本对象.这看起来很难,因为新的文本对象不能利用 QTextEdit/QTextDocument 中的现有基础设施。 .

QTextObject

a base class for different kinds of objects that can group parts of a QTextDocument together

所以继承它可能是一个选择,但是它在 Qt SDK 包中的源文件和 Google 搜索都没有找到有用的信息。

QTextFrame继承QTextObject因此,如果要找到有关此路径的一些提示,它可能是一个可行的基类。


在一个简单的 HTML 文件中,所有这一切(语法高亮除外)都很容易。 QTextEdit将 html 作为输入并能够导出 html,但结构在此过程中丢失。

<code class="code-sample">
int i = 0;
</code>

QWebView顺便说一句,它是只读的。它宣传说:

Parts of HTML documents can be editable for example through the contenteditable attribute on HTML elements.


可能其他平台也有这个功能,但文本编辑器需要在Qt Creator中作为插件使用,所以使用Qt框架是有道理的。

底线:如何在 QTextEdit 中实现代码区域小部件?


后期编辑:

  • 使用来自 trunk 的 Qt sdk(将自己标识为 4.8.4)
  • 来自主干的 Qt Creator(Qt Creator 2.6.81)

最佳答案

我发现使用QTextEdit/QTextDocument可以实现这个。我能想到的最简单的实现在这个答案中给出,供 future 寻求者引用。

请注意,保存/加载需要自定义,因为常规 .toHtml() 不会保留所需的信息。

插入代码块很简单:

QTextFrame * frame;

frame = cursor.insertFrame( code_block_format_ );
connect( frame, SIGNAL( destroyed() ),
this, SLOT( codeBlockDeleted() ) );
code_blocks_.append( frame );

注意您可以在类中保存的两个变量:

QTextFrameFormat code_block_format_;
QList<const QTextFrame*> code_blocks_;

我们需要框架的格式是一致的和有区别的。它可以在构造函数中初始化为:

code_block_format_.setBackground( QBrush( Qt::yellow ) );
code_block_format_.setBorder( 1 );
code_block_format_.setBorderStyle( QTextFrameFormat::BorderStyle_Inset);
code_block_format_.setMargin( 10 );
code_block_format_.setPadding( 4 );

我们需要这个列表来判断某个框架是否是代码框。由于所有继承 QTextObject 的对象都需要由 QTextDocument::createObject() 创建,我们不能简单地子类化 QTextFrame(实际上我认为我们可以,但还不确定)。

现在可以按照通常的方式将代码内容与其余部分分开:

for ( it = frame->begin(); !(it.atEnd()); ++it ) {
child_frame = it.currentFrame();
child_block = it.currentBlock();
if ( child_frame != NULL )
{
if ( code_blocks_.contains( frame ) )
{
/* ... */
}
}
} /* for ( it = frame->begin(); !(it.atEnd()); ++it ) */

但请注意,为了简洁起见,这被过度简化了。需要考虑嵌套框架。

如果您对完整实现感兴趣,请查看 git repository (正在进行中,2012 年 11 月)。

关于c++ - QTextEdit 中的自定义文本(代码)区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13517839/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com