关于QT 中QGraphicsItem 的鼠标事件

时间:2021-10-06 19:02:45
RT, 现有一个QGraphicsItem作为父Item  其下有若干继承自QGraphicsItem 的子Items
此时点击任一子Item都是没反应的  若希望点击某一子Item时改变该子Item的背景色 如何实现
我想着是要重写子Item的MousePressEvent() 
像下面这样
void Item::MousePressEvent( QGraphics~~~~~` * enent )
{
    this->setSelected();
}

void paint(...)
{
     ...
    if( this->isSelected() )
    {
        painter->setBrush( Qt::black );
    }
}
大概思路是这样,但是没有效果,感觉像是该鼠标按下事件没有被子Item接收到,请各位前辈不吝赐教

19 个解决方案

#1


你有没有重载 QGraphicsScene中的 事件过滤器或者 mousePressEvent的方法, Graphics里面的事件流是通过scene派发的,如果你在场景里面把事件给吞了,就是重载了mousePressEvent然后没做任何处理,没把事件在丢出来,这样就会把事件吞掉。或者在事件过滤器里面return true了,多会吞掉事件,那样你的item里面是接收不到事件的。即使你把焦点设置到item里面去也一样。

#2


同意
引用 1 楼  的回复:
你有没有重载 QGraphicsScene中的 事件过滤器或者 mousePressEvent的方法, Graphics里面的事件流是通过scene派发的,如果你在场景里面把事件给吞了,就是重载了mousePressEvent然后没做任何处理,没把事件在丢出来,这样就会把事件吞掉。或者在事件过滤器里面return true了,多会吞掉事件,那样你的item里面是接收不到事件的。即使你把焦点设置到i……

#3


是这样的  我以前没接触过QT  因为刚进公司 最近工作需要我做一个与这个相关的东西
目标是做一个控件   可惜不能上图

这个控件是像这样的 一个QGraphicsItem  里面包含若干子QGraphicsItem 
然后两个这种控件之间的 内部子Item  之间可以连线表示关系  当子QGraphicsItem 收到MousePressEvent
时作出反应表示被选中  比如说改变背景颜色
那么也就是说  我的工作只是做一个控件 不涉及到上面的QGraphicsScene 这一层 
还有我没有重写Scene里面关于事件的函数  Scene默认会吞掉事件吗?

#4


引用 3 楼  的回复:
是这样的  我以前没接触过QT  因为刚进公司 最近工作需要我做一个与这个相关的东西
目标是做一个控件   可惜不能上图

这个控件是像这样的 一个QGraphicsItem  里面包含若干子QGraphicsItem 
然后两个这种控件之间的 内部子Item  之间可以连线表示关系  当子QGraphicsItem 收到MousePressEvent
时作出反应表示被选中  比如说改……

如果你不用scene和view,连个效果都看不到,怎么知道控件做好了没有。

#5


scene和view 用了   其实我想说的是 是否这个控件对事件的响应需要依赖于具体的场景?
若是  怎么让事件从场景传下来到我希望的控件  要重写哪几个函数
我对QT的事件机制确实不怎么了解   多谢各位了

#6


不需要重写函数,scene对事件不做任何处理就可以了。

#7


我没有在Scene里面处理事件 
那么我现在需要在控件里面实现上述功能需要怎么做呢?

#8


我怎么觉得你这样应该是可以实现的呢/
你试试在
this->setSelected();
后面加上
qDebug()<<“event has taken”;
在painter->setBrush( Qt::black );
后面加上
qDebug()<<“has painted”;
看看具体是哪里出了错。

#9


引用 8 楼  的回复:
我怎么觉得你这样应该是可以实现的呢/
你试试在
this->setSelected();
后面加上
qDebug()<<“event has taken”;
在painter->setBrush( Qt::black );
后面加上
qDebug()<<“has painted”;
看看具体是哪里出了错。

没反应  貌似事件没传到这里 问题到底在哪里呢
我没有子类化QGraphicsView 和 QGraphicsScene

#10


贴下其他代码看看,生成 场景的,和 view的那块代码。

#11


这两部分没子类化
view = new QGraphicsView;
scene  = new QGraphicsScene;
scene->addGroup( 本控件 );
就是这样的.
本控件 是上下两部分,上半部分就是一个QGraphicsItem 只显示一个字符串
下部分如前面所言

#12


引用 9 楼  的回复:
引用 8 楼 的回复:

没反应 貌似事件没传到这里 问题到底在哪……


item应该是在最顶层,最先接收事件,不应该没有响应paitEvent啊?不过我没用过addgroup,以前都是用的单个的item,你看看是不是group有什么特别的地方

#13


刚才发现在Group 里面添加 
void mousePressEvent ( QGraphicsSceneMousePressEvent* event )
{
    QMessage msg( "Press" );
    msg.exec();
}
运行之后,开始不点group包含的范围 即点击其他空白的Scene部分 无对话框弹出 这个应该是预期的
然后点击Group部分  弹出对话框   这也是预期的
关键是  再无论点击Group内 还是其他空白区 都会弹出消息框 这。。。

#14


刚查了下文档,QGraphicsItemGroup也是有BoundingRect虚函数的,而不是直接根据里面放的item决定了。你是在继承QGraphicsItemGroup么?重写下它的boundingRect试试看行不行。另外你里面装的Item有没有写鼠标事件,group和item的接收鼠标事件的顺序我也不太清楚。还有你还可以用事件管理器来实现这些功能吗,就是EventFilter

#15


Item 里面写了鼠标事件  无反应
真的是弄不明白啊

#16


难道要沉了  。。。。   是不是Group类 的原因?

#17


引用 16 楼  的回复:
难道要沉了  。。。。   是不是Group类 的原因?

既然你用了group的话就重写group的鼠标事件,另外别忘了重写boundingRect函数,返回你需要的group的边框。
应该是没问题的。要是还不行,你就不用group了呗,想把item放一起,就定义个类型,移动一个的时候,让那个类型的跟着移动

#18


又学到不少东西

#19


你好 我也才学习 和你的问题基本一样 你的问题解决了吗 我还是不太熟悉Item scene的事件传递机制 
我仅仅是新建了一个scene 什么都没做 就是不响应鼠标点击事件 有时候反映只有在最大话 的时候才反映
这是什么原因

#1


你有没有重载 QGraphicsScene中的 事件过滤器或者 mousePressEvent的方法, Graphics里面的事件流是通过scene派发的,如果你在场景里面把事件给吞了,就是重载了mousePressEvent然后没做任何处理,没把事件在丢出来,这样就会把事件吞掉。或者在事件过滤器里面return true了,多会吞掉事件,那样你的item里面是接收不到事件的。即使你把焦点设置到item里面去也一样。

#2


同意
引用 1 楼  的回复:
你有没有重载 QGraphicsScene中的 事件过滤器或者 mousePressEvent的方法, Graphics里面的事件流是通过scene派发的,如果你在场景里面把事件给吞了,就是重载了mousePressEvent然后没做任何处理,没把事件在丢出来,这样就会把事件吞掉。或者在事件过滤器里面return true了,多会吞掉事件,那样你的item里面是接收不到事件的。即使你把焦点设置到i……

#3


是这样的  我以前没接触过QT  因为刚进公司 最近工作需要我做一个与这个相关的东西
目标是做一个控件   可惜不能上图

这个控件是像这样的 一个QGraphicsItem  里面包含若干子QGraphicsItem 
然后两个这种控件之间的 内部子Item  之间可以连线表示关系  当子QGraphicsItem 收到MousePressEvent
时作出反应表示被选中  比如说改变背景颜色
那么也就是说  我的工作只是做一个控件 不涉及到上面的QGraphicsScene 这一层 
还有我没有重写Scene里面关于事件的函数  Scene默认会吞掉事件吗?

#4


引用 3 楼  的回复:
是这样的  我以前没接触过QT  因为刚进公司 最近工作需要我做一个与这个相关的东西
目标是做一个控件   可惜不能上图

这个控件是像这样的 一个QGraphicsItem  里面包含若干子QGraphicsItem 
然后两个这种控件之间的 内部子Item  之间可以连线表示关系  当子QGraphicsItem 收到MousePressEvent
时作出反应表示被选中  比如说改……

如果你不用scene和view,连个效果都看不到,怎么知道控件做好了没有。

#5


scene和view 用了   其实我想说的是 是否这个控件对事件的响应需要依赖于具体的场景?
若是  怎么让事件从场景传下来到我希望的控件  要重写哪几个函数
我对QT的事件机制确实不怎么了解   多谢各位了

#6


不需要重写函数,scene对事件不做任何处理就可以了。

#7


我没有在Scene里面处理事件 
那么我现在需要在控件里面实现上述功能需要怎么做呢?

#8


我怎么觉得你这样应该是可以实现的呢/
你试试在
this->setSelected();
后面加上
qDebug()<<“event has taken”;
在painter->setBrush( Qt::black );
后面加上
qDebug()<<“has painted”;
看看具体是哪里出了错。

#9


引用 8 楼  的回复:
我怎么觉得你这样应该是可以实现的呢/
你试试在
this->setSelected();
后面加上
qDebug()<<“event has taken”;
在painter->setBrush( Qt::black );
后面加上
qDebug()<<“has painted”;
看看具体是哪里出了错。

没反应  貌似事件没传到这里 问题到底在哪里呢
我没有子类化QGraphicsView 和 QGraphicsScene

#10


贴下其他代码看看,生成 场景的,和 view的那块代码。

#11


这两部分没子类化
view = new QGraphicsView;
scene  = new QGraphicsScene;
scene->addGroup( 本控件 );
就是这样的.
本控件 是上下两部分,上半部分就是一个QGraphicsItem 只显示一个字符串
下部分如前面所言

#12


引用 9 楼  的回复:
引用 8 楼 的回复:

没反应 貌似事件没传到这里 问题到底在哪……


item应该是在最顶层,最先接收事件,不应该没有响应paitEvent啊?不过我没用过addgroup,以前都是用的单个的item,你看看是不是group有什么特别的地方

#13


刚才发现在Group 里面添加 
void mousePressEvent ( QGraphicsSceneMousePressEvent* event )
{
    QMessage msg( "Press" );
    msg.exec();
}
运行之后,开始不点group包含的范围 即点击其他空白的Scene部分 无对话框弹出 这个应该是预期的
然后点击Group部分  弹出对话框   这也是预期的
关键是  再无论点击Group内 还是其他空白区 都会弹出消息框 这。。。

#14


刚查了下文档,QGraphicsItemGroup也是有BoundingRect虚函数的,而不是直接根据里面放的item决定了。你是在继承QGraphicsItemGroup么?重写下它的boundingRect试试看行不行。另外你里面装的Item有没有写鼠标事件,group和item的接收鼠标事件的顺序我也不太清楚。还有你还可以用事件管理器来实现这些功能吗,就是EventFilter

#15


Item 里面写了鼠标事件  无反应
真的是弄不明白啊

#16


难道要沉了  。。。。   是不是Group类 的原因?

#17


引用 16 楼  的回复:
难道要沉了  。。。。   是不是Group类 的原因?

既然你用了group的话就重写group的鼠标事件,另外别忘了重写boundingRect函数,返回你需要的group的边框。
应该是没问题的。要是还不行,你就不用group了呗,想把item放一起,就定义个类型,移动一个的时候,让那个类型的跟着移动

#18


又学到不少东西

#19


你好 我也才学习 和你的问题基本一样 你的问题解决了吗 我还是不太熟悉Item scene的事件传递机制 
我仅仅是新建了一个scene 什么都没做 就是不响应鼠标点击事件 有时候反映只有在最大话 的时候才反映
这是什么原因

#20