做个外贸网站一般需要多少钱,成都网站建设哪家专业,学校的网站建设和资源库建设,公司代运营前言#xff1a; 我们需要先由一个 QGraphicsView#xff0c;这个是UI显示的地方#xff0c;也就是装满可见原色的Scene#xff0c;然后需要一个QGraphicsScene 用来管理所有可见的界面元素#xff0c;要实现UI功能#xff0c;我们需要用各种从QGraphicsItem拼装成UI控件…前言 我们需要先由一个 QGraphicsView这个是UI显示的地方也就是装满可见原色的Scene然后需要一个QGraphicsScene 用来管理所有可见的界面元素要实现UI功能我们需要用各种从QGraphicsItem拼装成UI控件并赋予他控件的逻辑。
简单的说QGraphicsView代表视图QGraphicsScene 代表场景QGraphicsItem代表图形项QGraphicsItem放在QGraphicsScene 中QGraphicsScene 放在QGraphicsView中。
1、坐标关系 这是QGraphicsView始终是以左上角为(0, 0)点单位为像素 创建场景QGraphicsScene 并放入视图中
QGraphicsScene* _scene new QGraphicsScene();
ui.graphicsView-setScene(_scene);注意如果设置scene的坐标和宽高则不能放在构造里不然不起效果设置图形项宽高和坐标也不能在构造设置。
scene的坐标怎么看 先忽略坐标看scene宽高如果scene宽高小于view宽高scene默认放到view正中央 如果scene宽高大于view宽高view视窗自动出现滚轮保证view宽高和scene宽高一致 如果scene宽高没有设置scene中没放图形项前宽高为0放入图形项后scene宽高会和图形项宽高保持一致且scene宽高和左上角坐标会随着图像同步变化scene就等同于图像scene宽高没有设置scene默认左上角坐标为(0, 0)原点也在左上角。scene宽高没有设置图像左上角坐标始终与scene左上角坐标重合。 然后看scene的(x, y)坐标(x, y)坐标为scene左上角坐标有点特别要注意不管scene左上角坐标如何变化scene整体始终处于view正中央。 如果scene的(x, y)为(0, 0)scene的原点也为(0, 0) 如果scene的(x, y)为(-scene-width() / 2, -scene-height() / 2)scene的原点在view正中央。 图像坐标系也是一个独立的坐标系图像左上角默认为(0, 0)点把图像放入scene图像左上角坐标默认在scene的原点设置图像左上角坐标
pixmapItem-setPos(-scene-width() / 2, -scene-height() / 2);这样图像左上角和scene左上角重合。
下面草图中继续说明三者坐标关系
2、viewscene和item三者坐标转换 上图中图片和矩形都放在QGraphicsItem里红点为图形项零点(0, 0)因为一旦有了QGraphicsItemscene会和item重合所以红点处也为scene零点坐标(0, 0)但区别在于红点往左边一点sence依然有坐标比如(-1, 0)但item直接返回空无法计算item坐标view视图坐标一直都是view显示框左上角为零点。
通过鼠标事件可以拿到视图view的坐标比如触发mousePressEvent事件 视图view坐标
QPoint nViewPoint event-pos();通过视图坐标转场景scene坐标
QPointF fScenePoint this-mapToScene(nViewPoint);通过场景坐标转图形项item坐标
QGraphicsItem* pItem this-scene()-itemAt(fScenePoint, QTransform()); //图形项指针
if (NULL ! pItem)
{QPointF fItemPoint pItem-mapFromScene(fScenePoint); //获取图形项坐标
}注意鼠标在不同的item上比如图片画的多边形点击一下不仅可以拿到该图形项Item坐标而且通过pItem拿到对应的item图形项指针
获取场景scene中所有Item图形项指针
QListQGraphicsItem* allItems scene-items();每个图形项都有一个type标识可以根据这个标识判断该图形项是图片矩形圆等等
if(allItems[0]-type() QGraphicsLineItem::Type)//直线
else if(allItems[0]-type() QGraphicsRectItem::Type)// 矩形
else if(allItems[0]-type() QGraphicsSimpleTextItem::Type)// 文本
//......3、在场景scene中绘制不同图形项 有时候我们会遇到这样一个问题 当我们重新继承一个图形项的类比如QGraphicsRectItem在自定义类中添加更多的关于矩形的功能创建矩形对象时却一直画不出矩形 需要把自定义类强转为QGraphicsRectItem类在设置绘制参数即可画出矩形如下所示。 通过如上方式画矩形QGraphicsRectItem会调用自己的paint事件画出矩形当drawRect继承QGraphicsRectItem同时又重写了paint方法假如在drawRect的paint事件里直接return用上面方法画矩形后会调用drawRect的paint方法然后直接return当然无法画出矩形。如果重写paint方法又想在重写的paint方法中调用QGraphicsRectItem的paint方法可以在paint方法中加上
QGraphicsRectItem::paint(painter, option, widget);这样可以在return之前调用父类的绘画方法画出矩形。
如果在drawRect类中重写paint方法当我实现了用鼠标画矩形的功能画出来的矩形用鼠标在矩形上点一下却拿不到矩形的item指针如下 原因在于drawRect继承了QGraphicsRectItem想要显示矩形并能拿到item指针需要在paint中把drawRect强转为QGraphicsRectItem指针再把更新的矩形数据QRect设置到QGraphicsRectItem中那么paint中最后面应该加上如下代码 另一种原因看不到绘制的图形项 这里先创建一个矩形设置到sence中然后再把图片设置到sence运行后只看到图片看不到画的矩形原因在于sence中的items会根据additem的顺序展示出来运行程序后先展示矩形然后展示图片但图片会覆盖矩形所以只能看到图片并不是矩形没有了如果先additem图片在additem矩形这样先展示图片然后会在图片上画出矩形这样可以正确显示。
4、其他一些补充 1界面变化触发resizeEvent事件想要图像实时在scene正中央需要在resizeEvent中设置
m_Scene-setSceneRect(m_PixmapItem-boundingRect());2如果在构造中创建矩形或图片并显示图片显示m_PixmapItem-setPixmap(pixmap);运行程序后会显示在view的左上角这时sence和item的(0,0)点在view的左上角。 如果先创建一个矩形不设置坐标和宽高先创建出来additem到sence然后等界面运行后通过点击按钮item-setRect(0,0,100,100)这样矩形会显示在view正中间。
3对一个item图元可设置焦点设置可选中设置可移动
item-setFlags(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsSelectable |QGraphicsItem::ItemIsMovable );4如果图片很大直接用QPixmap加载有可能在界面上显示不出来可以先把图片加载成QImage类型然后再把QImage转为QPixmap即可显示。或者设置图片缓存为0QPixmapCache::setCacheLimit(0)这个方法有待验证。
5图形项的各种事件
void mousePressEvent(QGraphicsSceneMouseEvent* event)
void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
void hoverEnterEvent(QGraphicsSceneHoverEvent* event); //鼠标移入图形项
void hoverLeaveEvent(QGraphicsSceneHoverEvent* event); //鼠标移出图形项
void contextMenuEvent(QGraphicsSceneContextMenuEvent* event); //右击菜单事件需要注意的是图形项中的鼠标移动事件mouseMoveEvent必须鼠标在图形项上按下移动才能触发这里没有setMouseTrack设置。使用鼠标在图形项上移入移出事件需要在构造中加入setAcceptHoverEvents(true); 还有一点需要注意想要图形项中的事件有相应必须在继承GraphicsView类中写好对应的事件并在事件中调用父事件使事件透传到item比如在界面画了一个矩形想要在矩形上右键进入contextMenuEvent事件必须在继承的GraphicsView类中重写contextMenuEvent事件并在事件中调用父类事件QGraphicsView::contextMenuEvent(event); 博客主页 主页 欢迎点赞 收藏 ⭐留言 如有错误敬请指正 本文由 梦回阑珊 原创首发于 CSDN转载注明出处 代码改变世界,你来改变代码✨