QGraphicItem, 拖拽窗口大小例子

该博客介绍了如何使用Qt的QGraphicItem实现窗口的拖拽大小功能,参照了Qt 4.7.1的boxes演示程序。内容中提到了关键代码部分,当鼠标悬停在特定红色区域时,鼠标样式会发生变化,允许用户进行窗口大小的调整。

参考: Qt\4.7.1\demos\boxes 所写。

例子表现: 如图。Hover到红色拖拽区域,鼠标样式改变。




重点语句已经做重点标记。

【.h】

class Graph : public QGraphicsItem
{

public:
	Graph(int x, int y);
	virtual ~Graph();

	QRectF boundingRect() const;

protected:
	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);

private:
	// 检测鼠标是否在重设大小的区域;
	bool IsInResizeArea(const QPointF& pos);  //重点

private:
	QSizeF	m_size;

	bool m_bIsResizing;        // 是否正在改变大小的过程中;

};
【.cpp】

const qreal g_cResizePos[] = {9, 6, 3};


Graph::Graph(int x, int y) :
	m_size(200, 200),
	m_bIsResizing(false)
{
	setAcceptHoverEvents(true);  //重点
	setPos(x, y);

	setFlag(QGraphicsItem::ItemIsMovable, true);  // 重点
	setFlag(QGraphicsItem::ItemIsSelectable, true);    // 重点
	setFlag(QGraphicsItem::ItemIsFocusable, true);  // 重点
}

Graph::~Graph()
{

}

QRectF Graph::boundingRect() const
{
	return  QRectF(0, 0, m_size.width(), m_size.height());
}

void Graph::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
	painter->setPen(Qt::black);
	painter->drawRect(boundingRect());

	if (option->state & QStyle::State_Selected)
	{
		painter->setRenderHint(QPainter::Antialiasing, true);  // 重点

		if (option->state & QStyle::State_HasFocus)
			painter->setPen(Qt::yellow);
		else
			painter->setPen(Qt::white);

		// draw frame
		painter->drawRect(boundingRect());

		// resize line
		qreal w = m_size.width();
        qreal h = m_size.height();
        painter->setPen(Qt::red);
        for (int i = 0; i < 3; ++i)
			painter->drawLine(w - g_cResizePos[i], h, w, h - g_cResizePos[i]);

		painter->setRenderHint(QPainter::Antialiasing, false);  // 重点
	}
}




void Graph::hoverMoveEvent(QGraphicsSceneHoverEvent* event)   // 重点
{
	if (m_bIsResizing || (IsInResizeArea(event->pos()) && isSelected()))
		setCursor(Qt::SizeFDiagCursor);
	else
		setCursor(Qt::ArrowCursor);

	QGraphicsItem::hoverMoveEvent(event);
}


void Graph::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
{
	if (m_bIsResizing)
	{
		qreal w = event->pos().x();
		qreal h = event->pos().y();
		if (w > 0)
			m_size.setWidth(w);
		if (h > 0)
			m_size.setHeight(h);

		prepareGeometryChange();  // 重点
	}
	else
	{
		QGraphicsItem::mouseMoveEvent(event);
	}
}


void Graph::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
	static qreal z = 0.0;
	setZValue(z += 1.0);

	if (event->button() == Qt::LeftButton && IsInResizeArea(event->pos()))
		m_bIsResizing = true;
	else
		QGraphicsItem::mousePressEvent(event);
}


void Graph::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
{
	if (event->button() == Qt::LeftButton && m_bIsResizing)
		m_bIsResizing = false;
	else
		QGraphicsItem::mouseReleaseEvent(event);
}



bool Graph::IsInResizeArea(const QPointF& pos)
{
	// algorithm step:                              // 重点
    // 1, dx = pos.x() - (m_size.width() - 9);
	// 2, pos.y() > (m_size.height() - dx);

	return (pos.x() - m_size.width() + g_cResizePos[0]) > (m_size.height() - pos.y());
}



评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值