Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a Qt interactive text editing widget

I want to develop an application with two main widgets one is a text editor and the other one is for graphic viewer.

enter image description here

The basic idea is to let the user hover over any block of code in the text area and the associated part of the drawing gets selected or highlighted.

For the graphic widget, after some research it seems QGraphicsScene fits the requirements the most, but I'm not sure what widget to use for the text editor such that it gives me a signal when hovering over any block of code (and also send a string parameter "id" of the block).

The reverse action is required too, so when the user choose to inspect element in the graphics view the text view is scrolled to view the associate block of code and highlight it (like in Google Chrome "Inspect Element" feature).

like image 952
Mahmoud Hassan Avatar asked Sep 26 '13 12:09

Mahmoud Hassan


Video Answer


2 Answers

You can use QTextEdit::cursorForPosition and QTextCursor::position to convert mouse coordinates to position in the text. You can determine the hovered code block using this position.

You can select arbitrary code block in the text edit as described in this answer.

QGraphicsScene seems to be a good choice, as it contains all the functionality you may need.

like image 90
Pavel Strakhov Avatar answered Oct 13 '22 00:10

Pavel Strakhov


To highlight text when an object is hovered in scene you have to reimplement QGraphicsScene and QGraphicsItem (which one you going to use) to inform mainwindow to find and highlight text. Here is sample code to highlight text when an object hovered in scene I used QGraphicsPixmapItem:


Graphic scene

 class GraphicScene : public QGraphicsScene
{
    Q_OBJECT
public:
    GraphicScene();

    void EmitItemHoverd(QString name)
    {
      emit SignalItemHovered(name);
    }


signals:
    void SignalItemHovered(QString);
};

GraphicsItem :

#include "GraphicScene.h"

class GraphicItem : public QGraphicsPixmapItem
{
    QString itemName;
    GraphicScene * scene;
public:
    GraphicItem(GraphicScene *s, QString name);//name you can set from editor

    void hoverEnterEvent(QGraphicsSceneHoverEvent *event);

};
GraphicItem::GraphicItem(GraphicScene *s, QString name)
{
    scene = s;
    itemName = name;
    this->setAcceptHoverEvents(true);
}

void GraphicItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
    scene->EmitItemHoverd(itemName);
}

in MainWindow constructor connect

connect(scene,SIGNAL(SignalItemHovered(QString)),this,SLOT(OnItemHovered(QString)));

Here is slot:

void MainWindow::OnItemHovered(QString name)
{
   ui->textEdit->find(name);
  QTextCursor tc = ui->textEdit->textCursor();
  tc.select(QTextCursor::WordUnderCursor);    
  ui->textEdit->find("}");
  QTextCursor tc1 = ui->textEdit->textCursor();
  tc1.select(QTextCursor::WordUnderCursor);
  int pos2 = tc1.selectionStart();

  tc.setPosition(pos2,QTextCursor::KeepAnchor);
  ui->textEdit->setTextCursor(tc);
}

and logic to draw:

    GraphicItem * item = new GraphicItem(scene,"Circle");

    QPixmap  map(50,50);
    QPainter * painter= new QPainter(&map);
    painter->setBrush(QBrush(Qt::red,Qt::SolidPattern));
    painter->drawEllipse(20,20,15,15);
    item->setPixmap(map);

    scene->addItem(item);
    ui->graphicsView->update();
    delete painter;

NOTE: Using public EmitItemHoverd may be an issue here I used just for sake of explaining the logic you can make it protected with required changes.

Yeah I knew its half of answer but opposite logic can be implimented based on above

like image 23
Tab Avatar answered Oct 13 '22 01:10

Tab