Qt GraphicsScene XOR Line或Line在单独的层中?

时间:2017-04-17 21:10:06

标签: c++ qt

我已经开始学习Qt,并尝试提高我的基本C ++技能。 在GraphicsScene中,我尝试使用鼠标绘制一条线(鼠标事件)。 当我开始在GraphicsScene中绘制一条线时,从原点绘制一条细虚线,在点击第二个点之前,我先点击当前鼠标位置并用鼠标移动。为了擦除它,我用黑色绘制它。如果我将鼠标悬停在已经绘制的线条上,您将看到它们上面的黑色绘制线条。为了在不留下标记的情况下绘制它,在GraphicsScene上进行XOR操作会派上用场,或者如果我可以在不同的层中绘制而不触及另一层则可以很方便。但我还不知道该怎么做。该示例位于https://github.com/JackBerkhout/QT_Draw001 在line.cpp中是函数setLineP2(int x,int y),它绘制并擦除那条细虚线。 有人可以帮帮我吗?

1 个答案:

答案 0 :(得分:0)

主要的错误观念是将QGraphicsScene视为某种位图:它不是!它是可以自我渲染的项目集合,以及它们的空间索引。在场景中,如果您想要删除/隐藏某些内容,您不得过度删除 - 而只需根据需要删除/隐藏相关项目。场景将处理所有细节 - 这就是它的用途

此时你必须忘记GDI。你不是在这里画上原始DC。即使使用原始GDI,你也不想在窗口的DC上绘画那样闪烁,你应该在位图上绘制并将位图blit到窗口。

例如,您的eraseScene方法在场景顶部添加了一个矩形,浪费了内存和资源,因为所有以前的项都被保留(您可以迭代它们),而它应该做的只是{{ 1}}场景(或其等价物):

clear

VS。正确的:

void MainWindow::eraseScreen(void)
{
    [...]
    scene->addRect(0, 0, width()+1000, height()+1000, pen, brush);
}

下面是一个完整的示例,它近似于您在代码中可能要执行的操作。 它长达120行。由于您的代码如此错综复杂,有点难以弄清楚您究竟打算做什么 - 在问题中以简单的术语描述确切行为很有用。

该示例使用void MainWindow::eraseScreen(void) { scene->clear(); } 来保留QPainterPath呈现MoveToLineTo元素的列表。它还使用QPainterPathItem来显示瞬态线。

QGraphicsLineItem用于包含修改路径的上下文,并确保维护正确的前后条件。即:

  1. 由于MyScene::PathUpdater是隐式共享的,因此您应该清除QPainterPath所持有的路径,以避免不必要的隐式副本。在修改QGraphicsPathItem之前,这是必要的前提条件。

  2. 修改m_path后,必须更新路径项,并发出新状态。

  3. 以下其他要点值得注意:

    1. 按值保存成员会导致显着缺少任何内存管理代码(!) - 编译器会为我们完成所有操作。您无法在任何地方找到单个m_pathnew。它们不是必需的,我们不会为不手动执行此操作而支付额外费用。现代C ++看起来应该是这样的。

    2. 显示deleteMainWindow之间的明确分割。 MySceneMainWindow的具体内容一无所知,反之亦然。 MyScene中的代码充当两者之间的适配器。

    3. 利用C ++ 11。

    4. SO测试用例和示例所需的简洁风格:学习它最好将其全部保存在一个文件中,以便轻松查看代码的所有部分。它只有120行,而不是文件分割的两倍多。我们的大脑利用参考的地方。通过拆分代码,你会让自己更难理解。

    5. 另见

      1. Another demo of interactive item creation
      2. A more advanced example of status notifications
      3. screenshot of the example code

        main