5

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

在此处输入图像描述

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

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

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

4

3 回答 3

4

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

您可以按照此答案中的说明在文本编辑中选择任意代码块。

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

于 2013-09-26T13:00:56.387 回答
2

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


图形场景

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

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


signals:
    void SignalItemHovered(QString);
};

图形项:

#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 可能是一个问题,我只是为了解释可以通过所需更改对其进行保护的逻辑。

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

于 2013-09-28T09:22:10.043 回答
1

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

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

于 2013-09-26T15:12:56.537 回答