设置 ItemIsMovable 标志时,子项在 QGraphicsView 中不可移动

2024-04-20

要调整项目中的项目QGraphicsView http://qt-project.org/doc/qt-5.0/qtwidgets/qgraphicsview.html,我将表示顶点的子项放到要移动的项上(使用构造函数中建立的父子关系)。就是下图中的四个蓝色圆圈:

但子顶点没有接收鼠标事件。只有父项(红色方块)正在获取鼠标事件。

这是定义Item:

Item::Item(QGraphicsItem * parent) :
    QGraphicsItem(parent)
{
    setFlag(ItemIsMovable);
    setFlag(ItemIsSelectable);
    setFlag(ItemSendsGeometryChanges);
    setCacheMode(DeviceCoordinateCache);   
}

void Item::paint(
    QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->fillRect(option->rect,Qt::red);
}

QVariant Item::itemChange(GraphicsItemChange change, const QVariant & value)
{
    switch(change)
    {
        case QGraphicsItem::ItemSelectedHasChanged:
            qWarning() << "item: " + value.toString();
            updateVertices(value.toBool());
            break;
        default:
            break;
    }
    return QGraphicsItem::itemChange(change, value);
}

void Item::updateVertices(bool visible) {
    if(visible) {
        if(vertices.length() == 0) {
            for(int i = 0; i < 4; i++)
                vertices.append(new Vertice(this));
        } else
            for(int i = 0; i < 4; i++)
                vertices[i]->setVisible(true);

        QRectF rect = boundingRect();
        vertices[0]->setPos(rect.topLeft());
        vertices[1]->setPos(rect.topRight());
        vertices[2]->setPos(rect.bottomLeft());
        vertices[3]->setPos(rect.bottomRight());
    } else {
        for(int i = 0; i < 4; i++) {
            p_vertices[i]->setVisible(false);
        }
    }
}

虽然这里是定义Vertice:

Vertice::Vertice(QGraphicsItem * parent) :
    QGraphicsItem(parent)
{
    setFlag(ItemIsMovable);
    setFlag(ItemIsSelectable);
    setFlag(ItemSendsGeometryChanges);
}

void Vertice::paint(
    QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->setBrush(Qt::blue);
    painter->setPen(Qt::darkGray);
    painter->drawEllipse(-5,-5,10,10);
}

QVariant Vertice::itemChange(GraphicsItemChange change, const QVariant & value)
{
    switch(change) {
        case QGraphicsItem::ItemSelectedHasChanged:
            qWarning() << "vertex: " + value.toString(); // never happened
            break;
        default:
            break;
    }
}

您说您的子项目没有收到鼠标事件,但它们确实收到了。您可以通过添加一个来验证这一点void mousePressEvent(QGraphicsSceneMouseEvent * event)到 Vertice 并注意到它被调用。

你的问题是 Qt 忽略了ItemIsMovable子 QGraphicsItem 上的标志。当你询问时它甚至没有设置标志。

您可以通过更改 Vertice 构造函数来验证这一点:

Vertice::Vertice(QGraphicsItem * parent) :
    QGraphicsItem(parent)
{
    setFlag(ItemIsMovable);
    Q_ASSERT(flags() & ItemIsMovable); // fails
    setFlag(ItemIsSelectable);
    setFlag(ItemSendsGeometryChanges);
}

为什么会这样呢?正如编程绝地所说:“使用源头,卢克!”

https://qt.gitorious.org/qt/qtbase/source/7df3321f934e5bd618e2ad00bf801f2b7edd31df:src/widgets/graphicsview/qgraphicsitem.cpp#L1789 https://qt.gitorious.org/qt/qtbase/source/7df3321f934e5bd618e2ad00bf801f2b7edd31df:src/widgets/graphicsview/qgraphicsitem.cpp#L1789

请注意,设置标志时它所做的事情之一是它提供了itemChange检查用ItemFlagsChange通知。不仅如此,它还允许该调用的结果覆盖标志。但是看看 Vertice 上 itemChange() 的实现:

QVariant Vertice::itemChange(GraphicsItemChange change, const QVariant & value)
{
    switch(change) {
        case QGraphicsItem::ItemSelectedHasChanged:
            qWarning() << "vertex: " + value.toString(); // never happened
            break;
        default:
            break;
    }
}

呃哦。无返回结果!将此行添加到末尾,就像您在项目中一样:

return QGraphicsItem::itemChange(change, value);

...你就得到了它。其他注意事项:

  • “顶点”的单数形式实际上是“顶点” https://english.stackexchange.com/questions/4539/singular-of-vertices

  • 如果您遇到这样的情况,请考虑将其从您正在编写的任何特定程序中删除。如果您可以用一个子项和一个父项来演示该问题,那么为什么要使用一个循环来生成四个呢?如果选择不是问题的一部分——并且不需要涉及隐藏和显示顶点的代码——那么为什么要涉及它呢?最好使用您提供的代码来提供所需的虚拟方法,例如boundingRect()而不是让别人写出来测试。看简短、独立、可编译的示例 http://sscce.org/

  • Qt 源代码具有相当的可读性并且组织良好,因此请养成查看它的习惯......!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

设置 ItemIsMovable 标志时,子项在 QGraphicsView 中不可移动 的相关文章

随机推荐

  • HashLocation 策略有什么缺点吗?

    我目前正在学习 Angular 我已经使用 HashLocation 实现了路由器 因为 PathLocation 在 Apache 服务器中不起作用 我浏览了各种帖子来解决这个问题 但最终不得不选择 Apache 的 HashLocati
  • 实体框架代码优先 - 将两个字段合并为一个集合

    我有这个型号和配置 public class Person public int FatherId get set public virtual Person Father get set public int MotherId get s
  • 使用内联要求

    如果我使用内联要求 如下所示 function something paths return require path join paths something etc etc 每次调用时引擎都需要吗 例子 let i 10 while i
  • 使用频带刻度的相同可重复字符串值

    我是 D3 的新手 想绘制带有 6 个水平条的图表 我的 xAxis 与它们的值是scaleLinear 的 所以我希望 yAxis 只是一个包含每个条形名称的列表 所以对于 yScale 我有 6 个名称 Games Apps Games
  • 禁用 Odoo 中看板列视图上的拖动和排序功能

    我正在 Odoo 9 中制作看板视图 以在基于 Many2one 字段的列中显示我的模型 我创建了这样的看板视图
  • matplotlib散点图颜色作为第三个变量的函数[重复]

    这个问题在这里已经有答案了 我想知道如何通过第三个变量使 matplotlib 的散点函数颜色点 问题matplotlib 中的 gnuplot linecolor 变量 https stackoverflow com questions
  • build.gradle 文件中的 IntelliJ 运行配置

    我有一个 Gradle 项目 目前可以通过以下方式导入到 IntelliJ 中 build gradle文件 IntelliJ 将设置正确的源位置并为我引入依赖项 我想做的是列出 IntelliJ 运行配置 build gradle文件 以
  • UIViewController 通话中状态栏问题

    Issue 通话状态栏消失后 模态呈现的视图控制器不会向上移动 在顶部留下 20px 的空白 透明空间 正常 没有问题 通话中 没有问题 通话中消失后 在顶部留下 20 像素高的空白 透明空间 显示下面的橙色视图 但是状态栏仍然存在于透明区
  • “您确定要离开此页面吗?”取消和确定功能

    我正在尝试执行类似于您离开的某些网站的操作 它会显示一个弹出窗口 显示 您确定要离开此页面吗 并有两个选项 取消 和 确定 我该如何做到这一点 并做到当您单击 取消 时 它只会取消该框 当他们单击 确定 时 它会执行 leaveChat 功
  • 如何仅在非整数时显示小数点?

    我用谷歌搜索过 但找不到正确的答案 假设我们有浮点数并得到它们的平均值 他们的平均值是这样的 3 5 2 5 5 7 所以我们有 4 个数字 不再在列表中的人 两个带小数的数字和两个整数 我想做的是 打印这些数字并保持这样 但我的问题是 当
  • JQuery ajax调用默认超时值

    我收到了无法复制的错误报告 但 ajax 调用超时是当前最好的猜测 所以我试图找出 jQuery 超时的默认值 ajax 称呼 有人有主意吗 在 jQuery 文档中找不到它 似乎没有标准化的默认值 我感觉默认是0 超时事件完全取决于浏览器
  • 使用 Javascript 将日期设置为 raddatepicker

    我从服务器端获取日期值并将其传递给 javascript 方法 然后使用 Javascript 将日期分配给 Telerik RadDatePicker 控件 我得到的日期为 var Date1 16 01 2013 00 00 00 fu
  • 更广泛的递归/泛型问题

    根据提出的问题和回答的问题here https stackoverflow com questions 6650532 recursive java generics between two classes 我有第二个 更复杂的一个 至少在
  • 如何过滤wireshark以仅查看从我的计算机发送/接收的dns查询?

    我是wireshark新手 正在尝试编写简单的查询 要查看仅从我的计算机发送或由我的计算机接收的 DNS 查询 我尝试了以下操作 dns and ip addr 159 25 78 7 其中 159 25 78 7 是我的 IP 地址 看起
  • IE11 中图标字体未加载

    我们使用 icomoon 作为图标字体 它们在 Chrome 和 Firefox 中运行良好 但在 IE11 中无法显示 有时 它似乎适用于第一个页面加载 但不适用于后续页面加载 清除缓存似乎不会重置它 其他IE版本也可能存在此问题 目前我
  • Android视频删除色度键背景

    我检查过this https stackoverflow com questions 12813089 i am working on android camera app i want to capture image and chang
  • Java 和 C/C++ 之间进程间通信的最快(低延迟)方法

    我有一个Java应用程序 通过TCP套接字连接到用C C 开发的 服务器 应用程序和服务器都在同一台机器 Solaris 机器 上运行 但我们最终正在考虑迁移到 Linux 交换的数据类型是简单消息 登录 登录ACK 然后客户端请求某些内容
  • 警告 - Perl 中的“哈希分配中的元素数量为奇数”

    我使用以下语法收到警告 my data variables Sno gt 5 0 ID gt 20 1 DBA gt 50 2 Address gt 80 3 Certificate gt 170 4 但在使用类似的语法时我没有收到类似的警
  • 将csv文件读取到“DataFrame”时如何指定索引的“dtype”?

    在 python 3 4 3 和 Pandas 0 16 中 如何指定dtype索引为str 以下代码是我尝试过的 In 1 from io import StringIO In 2 import pandas as pd In 3 imp
  • 设置 ItemIsMovable 标志时,子项在 QGraphicsView 中不可移动

    要调整项目中的项目QGraphicsView http qt project org doc qt 5 0 qtwidgets qgraphicsview html 我将表示顶点的子项放到要移动的项上 使用构造函数中建立的父子关系 就是下图