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





