Qt 可拖拽 大小可调 方框
程序员文章站
2022-06-17 09:38:56
...
Abstract
参考QGraphicItem, 拖拽窗口大小例子基本思路,结合公司项目需要,写出可以拖拽及调整大小的边框,并且边框内可以划分2x2或3x3网格
效果图
演示视频
链接: https://pan.baidu.com/s/1HOsTZESZVSh933phqCc43Q 提取码: i9wc
需求总结
- 方框,可以划分网格
- 方框在指定范围内*拖拽
- 可以拖拽方框四条边,改变方框大小
- 自适应缩放
分解+思路
可以参考Qt Window 大小调整,位置调整;
- 位置移动/大小调整 = 鼠标响应 + rect size position调整 + boundary restriction;
- 鼠标响应 = 鼠标press,move和hover event;
- rect resize and position = mouse move + 原始size和position
- boundary restriction = four vertex position check
部分代码
主要是event事件的里面处理方框移动,大小调整
virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget);
virtual void hoverMoveEvent(QGraphicsSceneHoverEvent* event);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
virtual void mousePressEvent(QGraphicsSceneMouseEvent* event);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent* event);
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
判断方框移动是否出界
//方框移动和size变化
void SCGridReszableRectItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if(m_resizing){
qreal x = pos().x();
qreal y = pos().y();
qreal eventX = event->pos().x();
qreal eventY = event->pos().y();
qreal moveX = 0;
qreal moveY = 0;
qreal newW = m_size.width();
qreal newH = m_size.height();
QRectF rect = scene()->sceneRect();
switch (m_curItemType) {
case ITEM_TYPE::TOP:
moveY = qMax(-y, eventY);
newH = m_size.height() - moveY;
break;
case ITEM_TYPE::BOTTOM:
newH = qMin(eventY, rect.height() - 2 - y);
break;
case ITEM_TYPE::LEFT:
moveX = qMax(-x, eventX);
newW = m_size.width() - moveX;
break;
case ITEM_TYPE::RIGHT:
newW = qMin(eventX, rect.width() - 2 - x);
break;
case ITEM_TYPE::CENTER:
break;
}
if(newH<minLength || newW<minLength) return;
moveBy(moveX, moveY);
m_size.setWidth(newW);
m_size.setHeight(newH);
prepareGeometryChange();
}
else{
qreal moveX = 0;
qreal moveY = 0;
qreal eventX = event->pos().x();
qreal eventY = event->pos().y();
moveY = m_originPos.y() - eventY;
moveX = m_originPos.x() - eventX;
moveOutSide(-moveX, -moveY);
}
}
//判断方框移动是否超出边界
void SCGridReszableRectItem::moveOutSide(qreal x, qreal y)
{
QRectF rect = scene()->sceneRect();
qreal itemX = pos().x();
qreal itemY = pos().y();
qreal limitW = rect.width() - m_size.width() - 2;
qreal limitH = rect.height() - m_size.height() - 2;
qreal newX = itemX + x;
qreal newY = itemY + y;
x = qMax(0.0, qMin(newX, limitW)) - itemX;
y = qMax(0.0, qMin(newY, limitH)) - itemY;
moveBy(x, y);
}
方框自适应scene size变化
//自适应大小
void SCGraphicsView::resizeEvent(QResizeEvent *event)
{
QSize newSize = event->size();
QSize oldSize =event->oldSize();
qreal scaleX = 1.0;
qreal scaleY = 1.0;
this->scene()->setSceneRect(0, 0, newSize.width(), newSize.height());
if(oldSize.width() <= 0)
return;
else{
scaleX = static_cast<qreal>(newSize.width())/oldSize.width();
scaleY = static_cast<qreal>(newSize.height())/oldSize.height();
}
QList<QGraphicsItem *>items = scene()->items();
foreach(QGraphicsItem *item, items){
if(item->type() == SCGridReszableRectItem::Type){
SCGridReszableRectItem *t = static_cast<SCGridReszableRectItem *>(item);
t->setScale(scaleX, scaleY);
QPointF pos = t->pos();
QPointF newPos = QPointF(pos.x() * scaleX, pos.y() * scaleY);
t->setPos(newPos);
}
}
}
代码运行环境
Mac OS + Qt Creator 4.11.0 + Qt 5.14.1
下载链接:https://download.csdn.net/download/u013883974/12741834
上一篇: Qt官方示例-Http
下一篇: 自定义Android 注解