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

Custom text (code) areas in QTextEdit

本文关键字:代码 区域 文本 自定义 QTextEdit      更新时间:2023-10-16

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

  • 独特的背景
  • 边界
  • 固定宽度字体
  • 可编辑内容
  • 实例需要对代码具有可识别性,以便可以提取其中的内容(将代码与周围的内容分开)
  • 保存/加载(从常规html文件)
  • 语法高亮显示是一个优点,但实际上并不是必需的

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


Qt提供了一个使用QTextEdit实现自定义文本对象的示例。这看起来很难,因为新的文本对象无法使用QTextEdit/QTextDocument中的现有基础结构。

QTextObject是

不同类型对象的基类,可以将QTextDocument的部分分组在一起

因此继承它可能是一种选择,但Qt SDK包中的源文件和谷歌搜索都没有显示有用的信息。

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


在一个简单的HTML文件中,所有这些(除了语法高亮显示)都很容易。QTextEdit以html作为输入,可以导出html,但结构在这个过程中丢失了。

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

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

HTML文档的某些部分可以编辑,例如通过HTML元素上的contenteditable属性。


可能还有其他平台可以随时使用,但文本编辑器需要在Qt Creator中作为插件使用,因此使用Qt框架是有意义的。

一句话:如何在QTextEdit小部件中实现代码区域?


后期编辑:

  • 使用trunk中的Qt-sdk(标识为4.8.4)
  • 来自主干的Qt创建者(Qt创建者2.6.81)

我发现使用QTextEdit/QTextDocument可以实现这一点。我能想到的最简单的实现方式在这个答案中给出,供未来的寻求者参考。

请注意,保存/加载需要按常规进行自定义。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存储库(正在进行中,2012年11月)。