求助关于QGraphicsItem的数学建模坐标问题题

代码-qt中鼠标点击view获取点并将坐标转换为scene坐标之后在坐标处绘制item,位置发生偏移
作者:用户
浏览:654 次
qt中鼠标点击view获取点并将坐标转换为scene坐标之后在坐标处绘制item,位置发生偏移如题,我的组件是用QGraphicsItem绘制的,重载了QMouseEvent,但是点击时在view上显
qt中鼠标点击view获取点并将坐标转换为scene坐标之后在坐标处绘制item,位置发生偏移
如题,我的组件是用QGraphicsItem绘制的,重载了QMouseEvent,但是点击时在view上显示的地方不对,主要代码如下:
QPoint viewPos = event-&pos();//获取视口坐标
QPointF scenePos = view_1-&mapToScene(viewPos);//将视口坐标转换为场景坐标
select-&setRect(scenePos.x(), scenePos.y(), 50, 50);//绘制圆圈
如图,鼠标点击位置与圆圈位置的偏移(当前我点击的是6那个点):
哪位大侠帮帮小弟一下,感激不尽!
已解决,是因为多层layout布局的原因,layout布局会有个margin,默认为11px。
希望对其他人有用。
解决方案二:
是我的问题太抽象了么?怎么没人回答啊,新手求救~~~
解决方案三:
是我的问题太抽象了么?怎么没人回答啊,新手求救~~~
【云栖快讯】红轴机械键盘、无线鼠标等753个大奖,先到先得,云栖社区首届博主招募大赛9月21日-11月20日限时开启,为你再添一个高端技术交流场所&&
稳定可靠、可弹性伸缩的在线数据库服务,全球最受欢迎的开源数据库之一
6款热门基础云产品6个月免费体验;2款产品1年体验;1款产品2年体验
弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率
开发者常用软件,超百款实用软件一站式提供关于Qt&Graphics编程的几点经验总结
好久没有写任何关于编程方面的东西了。这阵子偶尔用Qt的Graphics模块,略有一点经验总结,简单写在这里,权当做自己的备忘录。
Graphics模块用于显示二维的图形图像,所以三维的事情就不要找它了,应该去找Qt的OpenGL模块。主要由三部分组成,分别是View,
Scene, Item。
QGraphicsView负责窗口显示,它继承自QWidget,因此是一个标准的Qt窗口类,Qt窗口类一般的操作QGraphicsView都支持。QGraphicsScene是一个视图,它不能够单独存在,必须关联到至少一个QGraphicsView。这两者的关系就和MVO架构中的文档和视图的关系类似,View是视图,负责显示;Scene是文档,负责存储数据。所以从这个角度出发,我们可以这样认为,一个Scene可以关联到多个View,就好比一份数据可以有多个视图去查看它一样。
Item则是具体要显示的东西。最基本的Qt类就是QGraphicsItem,一般如果要显示自定义的形状通常的做法是继承自QGraphicsItem,然后去实现它的两个纯虚函数boundingRect和paint,它们的形式化申明如下:
virtual QRectF boundingRect () const = 0
virtual void paint ( QPainter * painter, const
QStyleOptionGraphicsItem * option, QWidget * widget = 0 ) = 0
boundingRect就是返回该Item的包围盒,用于Graphics内部的碰撞检测以及选取等计算。paint则是用于Item的重绘。
除最基本的QGraphicsItem之外,Qt还定义了若干基本形状的Item,例如QGraphicsEllipseItem、QGraphicsLineItem、QGraphicsRectItem等等,具体可查Qt文档。如果想要绘制的Item形状和这些基本类型接近,不妨直接继承自这些类,然后在paint函数中稍加修改。
Qt之所以提供Graphics模块是为了对二维图形编程方面提供基本的常用的平台功能支持,例如拖动、选择、旋转、动画、缩放、碰撞检测等等。这些功能,简言之,如果我们要用,是不必像在MFC上那样大费周折的,Qt
Graphics提供了很好的操作接口。例如,要使得Item能够被选择,只需要设置它的Flag:
setFlag (QGraphicsItem::ItemIsMovable);
即可。移动、是否能获取焦点等都类似。
Qt默认情况下,对于选中的Item,如果你是继承自特殊形状的子类,则会在Item的包围框上显示虚框。若要去掉该虚框,则在paint函数中加入如下代码:
QStyleOptionGraphicsItem op(*option );&
op. state = QStyle:: State_N
然后调用父类的paint函数时,将op作为option传入即可。如果要使得选中的Item呈现不同的状态(颜色、大小等)也是在paint函数中加以修改。
QGraphicsView和QGraphicsScene以及QGraphicsItem都能够接受鼠标、键盘事件,那他们的关系又是如何呢?首先从消息流来看,先是View,然后是Scene,最后是Item。任何阶段若节流事件,则下一层就不会再接受到事件了。对于QGraphicsView和QGraphicsScene,我们应该在哪里处理鼠标或者键盘事件呢?其实两者都是可以的,具体看需求。联系之前所说的文档视图关系可以知道,若应用程序中只有一个View和一个Scene,那么其实在哪里实现都无所谓;当时如果一个Scene对应了多个View,则就有区别了。如果具体到一个视图的操作,应该在View类中实现;如果是Scene需要统一进行处理的,那么就应该在Scene中实现。
Scene更新的时候,尽可能将更新范围限制在最小内,毕竟update全局的话需要消耗较多的资源,尤其是显示内容比较大的时候,会不流畅。
获取鼠标下面的item方法是itemAt。若在View中调用此函数,注意它的参数坐标是View中的坐标,即不需要再做任何的转化。
GraphicsScene中可以内嵌入标准的QWidget,但是其行为和正常的widget略有不同。我发现的一点是:只有真正在Scene中显示的时候,其内部控件才是真正存在的,否则ui内的指针均无效。估计是为了节约资源考虑的吧。这点切记!
QGraphicsItemAnimation可以实现一些简单的动画操作,亲测效果还是不错的,较为平滑。
暂记这些,有问题可以讨论。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。#include &QtWidgets&
//自定义item需要重写的两个函数boudingRect()和paint()
class CheckBoxItem : public QGraphicsObject
CheckBoxItem(int w, int h, const QString &text, const QString &checkedIcon, const QString &emptyIcon, QGraphicsObject *parent = 0);
QRectF boundingRect() //用来设置该item的大小 必须
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)//用来绘制该item的东西 必须
bool isChecked();
void setChecked(bool checked);
void stateChanged(bool checked);
protected:
void keyPressEvent(QKeyEvent * event)
void mousePressEvent(QGraphicsSceneMouseEvent *event)
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
QString m_
QPixmap m_checkedI
QPixmap m_emptyI
bool m_leftButtonD
CheckBoxItem::CheckBoxItem(int w, int h, const QString &text, const QString &checkedIcon, const QString &emptyIcon, QGraphicsObject *parent) :
m_width(w),
m_height(h),
m_text(text),
m_checkedIcon(checkedIcon),
m_emptyIcon(emptyIcon),
QGraphicsObject(parent), m_leftButtonDown(false)
setFlag(QGraphicsItem::ItemIsFocusable, true); //用来设置这个item可以获取焦点
QRectF CheckBoxItem::boundingRect() const
return QRectF(0,0, m_width, m_height);
//调用这里面的painter画家进行绘制图形
void CheckBoxItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
Q_UNUSED(option)
Q_UNUSED(widget)//这个宏是用来把不用到的参数注掉的功能
int x = 2;
int y = (m_height - m_checkedIcon.height()) / 2;
painter-&drawPixmap(x, y, m_checked ? m_checkedIcon : m_emptyIcon);
if(!m_text.isEmpty())
x = x + m_checkedIcon.width() + 4;
QRect rc(x, 0, m_width - x - 2, m_height);
painter-&drawText(rc, Qt::AlignVCenter | Qt::AlignLeft, m_text);
void CheckBoxItem::keyPressEvent(QKeyEvent *event)
if(event-&key() == Qt::Key_Space)
event-&accept();
m_checked = !m_
void CheckBoxItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
if(event-&button() == Qt::LeftButton)
m_leftButtonDown =
event-&accept();
void CheckBoxItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
if(event-&button() == Qt::LeftButton)
m_leftButtonDown =
m_checked = !m_
event-&accept();
emit stateChanged(m_checked);
阅读(...) 评论()

我要回帖

更多关于 matlab怎么改坐标问题 的文章

 

随机推荐