用qt实现一个可以用鼠标改变大小,方向和位置的矩形
时间: 2023-06-10 20:06:01 浏览: 281
可以通过继承QWidget或QFrame,并重写paintEvent、mousePressEvent、mouseMoveEvent和mouseReleaseEvent函数,实现一个自定义的矩形控件。
首先,在头文件中定义一个类,例如MyRect:
```cpp
class MyRect : public QFrame
{
Q_OBJECT
public:
explicit MyRect(QWidget *parent = nullptr);
protected:
void paintEvent(QPaintEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
private:
bool m_isResizing;
bool m_isMoving;
QPoint m_dragStart;
QRect m_rect;
};
```
在构造函数中初始化一些变量:
```cpp
MyRect::MyRect(QWidget *parent)
: QFrame(parent)
, m_isResizing(false)
, m_isMoving(false)
{
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
setCursor(Qt::SizeAllCursor);
setMouseTracking(true);
}
```
重写paintEvent函数,绘制矩形:
```cpp
void MyRect::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(QPen(Qt::black, 2));
painter.setBrush(QBrush(Qt::lightGray));
painter.drawRect(m_rect);
}
```
重写mousePressEvent函数,检查鼠标是否在矩形边框内或矩形内部,以及是否在矩形边框上进行大小调整:
```cpp
void MyRect::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
if (m_rect.contains(event->pos())) {
m_isMoving = true;
m_dragStart = event->pos() - m_rect.topLeft();
} else {
QList<QRect> resizeRects = {
QRect(m_rect.left() - 2, m_rect.top() - 2, 4, 4),
QRect(m_rect.right() - 2, m_rect.top() - 2, 4, 4),
QRect(m_rect.left() - 2, m_rect.bottom() - 2, 4, 4),
QRect(m_rect.right() - 2, m_rect.bottom() - 2, 4, 4)
};
foreach (const QRect &resizeRect, resizeRects) {
if (resizeRect.contains(event->pos())) {
m_isResizing = true;
m_dragStart = event->pos();
break;
}
}
}
}
}
```
重写mouseMoveEvent函数,实现矩形大小调整和位置移动:
```cpp
void MyRect::mouseMoveEvent(QMouseEvent *event)
{
if (m_isMoving) {
m_rect.moveTopLeft(event->pos() - m_dragStart);
update();
} else if (m_isResizing) {
int dx = event->pos().x() - m_dragStart.x();
int dy = event->pos().y() - m_dragStart.y();
if (m_dragStart.x() == m_rect.left()) {
m_rect.setLeft(m_rect.left() + dx);
} else {
m_rect.setRight(m_rect.right() + dx);
}
if (m_dragStart.y() == m_rect.top()) {
m_rect.setTop(m_rect.top() + dy);
} else {
m_rect.setBottom(m_rect.bottom() + dy);
}
m_dragStart = event->pos();
update();
} else {
QList<QRect> resizeRects = {
QRect(m_rect.left() - 2, m_rect.top() - 2, 4, 4),
QRect(m_rect.right() - 2, m_rect.top() - 2, 4, 4),
QRect(m_rect.left() - 2, m_rect.bottom() - 2, 4, 4),
QRect(m_rect.right() - 2, m_rect.bottom() - 2, 4, 4)
};
bool cursorChanged = false;
foreach (const QRect &resizeRect, resizeRects) {
if (resizeRect.contains(event->pos())) {
setCursor(getResizeCursor(resizeRect));
cursorChanged = true;
break;
}
}
if (!cursorChanged) {
setCursor(Qt::SizeAllCursor);
}
}
}
```
重写mouseReleaseEvent函数,重置一些变量:
```cpp
void MyRect::mouseReleaseEvent(QMouseEvent *event)
{
Q_UNUSED(event);
m_isResizing = false;
m_isMoving = false;
}
```
getResizeCursor函数用于根据鼠标位置返回正确的光标类型:
```cpp
Qt::CursorShape MyRect::getResizeCursor(const QRect &rect) const
{
if (rect.top() == m_rect.top()) {
if (rect.left() == m_rect.left()) {
return Qt::SizeFDiagCursor;
} else {
return Qt::SizeBDiagCursor;
}
} else {
if (rect.left() == m_rect.left()) {
return Qt::SizeBDiagCursor;
} else {
return Qt::SizeFDiagCursor;
}
}
}
```
最后,在主窗口中使用MyRect控件即可:
```cpp
MyRect *rect = new MyRect(this);
rect->setGeometry(50, 50, 100, 100);
```
这样就可以通过鼠标改变矩形的大小、方向和位置了。
阅读全文