Custom Text (Code) Areas in QTextEdit

I'm interested in creating a type of text object (inheriting from QTextObjectInterface ) that behaves like a code region:

  • distinctive background
  • the border
  • fixed width font
  • editable content
  • instances must be identifiable for the code, so the contents inside them can be extracted (separate code from the surrounding content)
  • save / load (from regular html files)
  • syntax highlighting will be a plus, but not really required

Other areas of the document should behave in the usual way (font properties are editable, editable colors, etc.).


Qt provides an example for implementing custom text objects with QTextEdit . This looks complicated because the new text object cannot use the existing infrastructure inside QTextEdit / QTextDocument .

QTextObject

base class for various types of objects that can group parts of a QTextDocument together

therefore, inheritance may be a choice, but neither its source files in the Qt SDK package, nor Google search queries showed useful information.

A QTextFrame inherits a QTextObject , so again, it can be a valid base class if you need to find some clues about this path.


In a simple HTML file, all this (except for syntax highlighting) would be simple. QTextEdit accepts html as input file and can export html, but the structure is lost in the process.

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

QWebView is read-only. He advertises that:

Parts of HTML documents can be edited, for example, through the contenteditable attribute for HTML elements.


There may be other platforms where this is available, but a text editor needs to be used inside Qt Creator as a plug-in, so using a Qt infrastructure makes sense.

Bottom line: how to implement code areas in a QTextEdit widget?


Late changes:

  • using Qt sdk from trunk (identifies itself as 4.8.4)
  • Qt Creator from the torso (Qt Creator 2.6.81)
+4
source share
1 answer

I found that implementing this is possible using QTextEdit / QTextDocument. The simplest implementation that I can think of is presented in this answer for the reference of the future seeker.

Please note that saving / loading must be configured as regular .toHtml (), without saving the necessary information.

Inserting code is very simple:

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

pay attention to two variables that you can save in the class:

 QTextFrameFormat code_block_format_; QList<const QTextFrame*> code_blocks_; 

We need a format so that it is consistent and distinctive. Its mat is initialized in the constructor like this:

 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 ); 

We need a list so that we can determine if a particular frame is coded or not. Since all objects that inherit from QTextObject must be created by QTextDocument :: createObject (), we cannot simply subclass QTextFrame (in fact, I think we can, but are not sure yet).

Now the separation of the contents of the code from the rest can be performed in the usual way:

 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 ) */ 

but note that this is simplified for brevity. It is necessary to consider the nested frames.

If you are interested in a full implementation, check out the git repository (work continues, November 2012).

+4
source

Source: https://habr.com/ru/post/1447791/


All Articles