如何制作Qt交互式文本编辑小部件

Mah*_*san 5 qt qwidget qwebview qgraphicsscene qtextbrowser

我想开发一个带有两个主要小部件的应用程序,一个是文本编辑器,另一个是图形查看器.

在此输入图像描述

基本思想是让用户将鼠标悬停在文本区域中的任何代码块上,并且选择或突出显示图形的相关部分.

对于图形小部件,经过一些研究后,似乎QGraphicsScene最符合要求,但我不确定用于文本编辑器的小部件,以便在将鼠标悬停在任何代码块上时给我一个信号(并且还发送一个块的字符串参数"id").

也需要相反的操作,因此当用户选择在图形视图中检查元素时,滚动文本视图以查看关联的代码块并突出显示它(例如在谷歌浏览器"检查元素"功能中).

Tab*_*Tab 2

要在对象悬停在场景中时突出显示文本,您必须重新实现 QGraphicsScene 和 QGraphicsItem(您将使用哪一个)来通知主窗口查找并突出显示文本。以下是当对象悬停在我使用 QGraphicsPixmapItem 的场景中时突出显示文本的示例代码:


图文场景

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

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


signals:
    void SignalItemHovered(QString);
};
Run Code Online (Sandbox Code Playgroud)

图形项目:

#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);
}
Run Code Online (Sandbox Code Playgroud)

在 MainWindow 构造函数中连接

connect(scene,SIGNAL(SignalItemHovered(QString)),this,SLOT(OnItemHovered(QString)));
Run Code Online (Sandbox Code Playgroud)

这是插槽:

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);
}
Run Code Online (Sandbox Code Playgroud)

和绘制逻辑:

    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;
Run Code Online (Sandbox Code Playgroud)

注意:使用 public EmitItemHoverd 可能是一个问题,我使用它只是为了解释逻辑,您可以通过所需的更改对其进行保护。

是的,我知道答案的一半,但可以根据上面的内容实现相反的逻辑

  • 谢谢 Tab,我已经操纵了你很多代码,但基本思想是关键,为了记录,我使用了这个主题 http://qt-project.org/doc/qt-4.8/widgets-codeeditor.html 作为代码区域,到目前为止效果很好:) (2认同)