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

时间:2013-09-26 12:06:13

标签: qt qwidget qwebview qgraphicsscene qtextbrowser

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

enter image description here

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

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

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

3 个答案:

答案 0 :(得分:4)

您可以使用QTextEdit::cursorForPositionQTextCursor::position将鼠标坐标转换为文本中的位置。您可以使用此位置确定悬停的代码块。

您可以按照this answer

中的说明在文本编辑中选择任意代码块

QGraphicsScene似乎是一个不错的选择,因为它包含了您可能需要的所有功能。

答案 1 :(得分:2)

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


图形场景

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

在MainWindow构造函数连接中

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

这是插槽:

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

和绘制逻辑:

    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;

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

是的,我知道答案的一半,但基于上面

可以证明相反的逻辑

答案 2 :(得分:1)

我会在QML中完全尝试这一点。我会使文本编辑器成为文本区域列表(可能为所需的格式创建一个新的QML项目)。列表中的每个项目实际上都是新创建的QML项目(适合转储到.qml文件中并在较高项目中引用)。此时,您可以将每个项目注入左侧的QML视图中,仅在悬停或单击该区域时添加鼠标处理程序。

因此,左侧是一个QML场景,由控制器管理和更新,该控制器从右侧的项目列表中获取原始文本并尝试将其解析为新的QML类型。根据我脑海中的理论,它应该可以工作,它会减少大量的复杂性(特别是将鼠标点直接映射到文本体中)。