实现的效果:如下图:主要是紫色的方块能在graphicsView里面自由移动 + 紫色方块能自由拉伸(整个代码复制过去就可以用了)
具体代码如下:
1.创建一个项目(默认的就行了)
2.创建 (紫色方块)
AutoSizeWidget.cpp
#pragma execution_character_set("utf-8")
#include "AutoSizeWidget.h"
#include "ui_autosizewidget.h"
#include <QDebug>
AutoSizeWidget::AutoSizeWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::AutoSizeWidget)
{
ui->setupUi(this);
this->setWindowFlags(Qt::FramelessWindowHint);//去掉标题栏
//this->setAttribute(Qt::WA_StyledBackground,true);
isLeftPressDown = false;
dir = NONE;
// 追踪鼠标
this->setMouseTracking(true);
}
AutoSizeWidget::~AutoSizeWidget()
{
delete ui;
}
void AutoSizeWidget::judgeRegionSetCursor(const QPoint& currentPoint)
{
// 获取窗体在屏幕上的位置区域,tl为topleft点,rb为rightbottom点
QRect rect = this->rect();
QPoint tl = mapToParent(rect.topLeft());
QPoint rb = mapToParent(rect.bottomRight());
int x = currentPoint.x();
int y = currentPoint.y();
if (tl.x() + Padding >= x && tl.x() <= x && tl.y() + Padding >= y && tl.y() <= y) {
// 左上角
dir = LEFTTOP;
this->setCursor(QCursor(Qt::SizeFDiagCursor)); // 设置鼠标形状
}
else if (x >= rb.x() - Padding && x <= rb.x() && y >= rb.y() - Padding && y <= rb.y()) {
// 右下角
dir = RIGHTBOTTOM;
this->setCursor(QCursor(Qt::SizeFDiagCursor));
}
else if (x <= tl.x() + Padding && x >= tl.x() && y >= rb.y() - Padding && y <= rb.y()) {
//左下角
dir = LEFTBOTTOM;
this->setCursor(QCursor(Qt::SizeBDiagCursor));
}
else if (x <= rb.x() && x >= rb.x() - Padding && y >= tl.y() && y <= tl.y() + Padding) {
// 右上角
dir = RIGHTTOP;
this->setCursor(QCursor(Qt::SizeBDiagCursor));
}
else if (x <= tl.x() + Padding && x >= tl.x()) {
// 左边
dir = LEFT;
this->setCursor(QCursor(Qt::SizeHorCursor));
}
else if (x <= rb.x() && x >= rb.x() - Padding) {
// 右边
dir = RIGHT;
this->setCursor(QCursor(Qt::SizeHorCursor));
}
else if (y >= tl.y() && y <= tl.y() + Padding) {
// 上边
dir = UP;
this->setCursor(QCursor(Qt::SizeVerCursor));
}
else if (y <= rb.y() && y >= rb.y() - Padding) {
// 下边
dir = DOWN;
this->setCursor(QCursor(Qt::SizeVerCursor));
}
else {
// 默认
dir = NONE;
this->setCursor(QCursor(Qt::ArrowCursor));
}
}
void AutoSizeWidget::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
isLeftPressDown = false;
if (dir != NONE) {
this->releaseMouse();
this->setCursor(QCursor(Qt::ArrowCursor));
}
}
}
void AutoSizeWidget::mousePressEvent(QMouseEvent *event)
{
switch (event->button()) {
case Qt::LeftButton:
isLeftPressDown = true;
if (dir != NONE) {
this->mouseGrabber();
}
else {
dragPosition = event->globalPos() - this->frameGeometry().topLeft();
}
break;
default:
QWidget::mousePressEvent(event);
}
}
void AutoSizeWidget::mouseMoveEvent(QMouseEvent *event)
{
QPoint gloPoint = mapToParent(event->pos());
QRect rect = this->rect();
QPoint tl = mapToParent(rect.topLeft());
QPoint rb = mapToParent(rect.bottomRight());
qDebug()<<"鼠标移动位置"<<gloPoint
<<"矩形左上角坐标 "<<tl
<<"矩形右下角坐标 "<<rb;
if (!isLeftPressDown) {
this->judgeRegionSetCursor(gloPoint);
}
else {
qDebug()<<"左键是否点击 是";
if (dir != NONE) {
qDebug()<<"状态 "<<dir;
QRect rMove(tl, rb);
switch (dir) {
case LEFT:
if (rb.x() - gloPoint.x() <= this->minimumWidth())
rMove.setX(tl.x());
else
rMove.setX(gloPoint.x());
break;
case RIGHT:
rMove.setWidth(gloPoint.x() - tl.x());
break;
case UP:
if (rb.y() - gloPoint.y() <= this->minimumHeight())
rMove.setY(tl.y());
else
rMove.setY(gloPoint.y());
break;
case DOWN:
rMove.setHeight(gloPoint.y() - tl.y());
break;
case LEFTTOP:
if (rb.x() - gloPoint.x() <= this->minimumWidth())
rMove.setX(tl.x());
else
rMove.setX(gloPoint.x());
if (rb.y() - gloPoint.y() <= this->minimumHeight())
rMove.setY(tl.y());
else
rMove.setY(gloPoint.y());
break;
case RIGHTTOP:
rMove.setWidth(gloPoint.x() - tl.x());
rMove.setY(gloPoint.y());
break;
case LEFTBOTTOM:
rMove.setX(gloPoint.x());
rMove.setHeight(gloPoint.y() - tl.y());
break;
case RIGHTBOTTOM:
rMove.setWidth(gloPoint.x() - tl.x());
rMove.setHeight(gloPoint.y() - tl.y());
break;
default:
break;
}
this->setGeometry(rMove);
}
else {
move(event->globalPos() - dragPosition);
event->accept();
}
}
QWidget::mouseMoveEvent(event);
}
AutoSizeWidget.h
#ifndef AUTOSIZEWIDGET_H
#define AUTOSIZEWIDGET_H
#include <QWidget>
#include <QMouseEvent>
//#include "basewidget.h"
//这是mainWindow的基类,继承与QWidget,实现了可拉伸大小
enum Direction {
UP, DOWN, LEFT, RIGHT, LEFTTOP, LEFTBOTTOM, RIGHTBOTTOM, RIGHTTOP, NONE
};
namespace Ui {
class AutoSizeWidget;
}
class AutoSizeWidget : public QWidget
{
Q_OBJECT
public:
explicit AutoSizeWidget(QWidget *parent = 0);
~AutoSizeWidget();
protected:
void mouseMoveEvent(QMouseEvent *) override;
void mousePressEvent(QMouseEvent *) override;
void mouseReleaseEvent(QMouseEvent *) override;
private:
Ui::AutoSizeWidget *ui;
void judgeRegionSetCursor(const QPoint&);
const int Padding = 2;
bool isLeftPressDown; // 判断左键是否按下
QPoint dragPosition; // 窗口移动拖动时需要记住的点
// 窗口大小改变时,记录改变方向
Direction dir;
};
#endif // AUTOSIZEWIDGET_H
AutoSizeWidget.ui (大小随意)
3.创建蓝色方块(不需要就不要加了,主要是紫色方块功能)
BaseWidget.cpp
#include "BaseWidget.h"
#include "ui_BaseWidget.h"
BaseWidget::BaseWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::BaseWidget)
{
ui->setupUi(this);
}
BaseWidget::~BaseWidget()
{
delete ui;
}
BaseWidget.h
#ifndef BASEWIDGET_H
#define BASEWIDGET_H
#include <QWidget>
namespace Ui {
class BaseWidget;
}
class BaseWidget : public QWidget
{
Q_OBJECT
public:
explicit BaseWidget(QWidget *parent = 0);
~BaseWidget();
private:
Ui::BaseWidget *ui;
};
#endif // BASEWIDGET_H
BaseWidget.ui
4.在MainWindow里面加入graphicsView,还有蓝色和紫色方块
MainWindow.cpp
#include "AutoSizeWidget.h"
#include "BaseWidget.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QGraphicsScene *scene = new QGraphicsScene;
ui->graphicsView->setScene(scene);
scene->setSceneRect(ui->graphicsView->rect());
//ui->graphicsView->resize(600,400);
ui->graphicsView->show();
BaseWidget *w = new BaseWidget();
w->move(100,100);
scene->addWidget(w);
BaseWidget *w1 = new BaseWidget();
w1->move(355,100);
scene->addWidget(w1);
BaseWidget *w2 = new BaseWidget();
w2->move(100,255);
scene->addWidget(w2);
BaseWidget *w3 = new BaseWidget();
w3->move(355,255);
scene->addWidget(w3);
AutoSizeWidget *item = new AutoSizeWidget();
scene->addWidget(item);
}
MainWindow::~MainWindow()
{
delete ui;
}
MainWindow.ui
5.运行就可以了(整个代码复制就可以用了)