123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456 |
- #pragma execution_character_set("utf-8")
- #include "selectwidget.h"
- SelectWidget::SelectWidget(QWidget *parent) : QWidget(parent)
- {
- drawPoint = false;
- padding = 5;
- borderWidth = 1;
- pointSize = 8;
- pointColor = QColor(34, 163, 168);
- pointStyle = PointStyle:: PointStyle_Rect;
- pressed = false;
- pressedLeft = false;
- pressedRight = false;
- pressedTop = false;
- pressedBottom = false;
- pressedLeftTop = false;
- pressedRightTop = false;
- pressedLeftBottom = false;
- pressedRightBottom = false;
- widget = 0;
- // 增加:控件的类型的和指针
- m_Type = VALUE_TYPE::Type_Unknown;
- m_pProperty = nullptr;
- // 扩展属性
- m_pPropertyEx = nullptr;
- //设置鼠标追踪为真,并绑定事件过滤器,可以获取焦点用于按键移动位置
- this->setMouseTracking(true);
- //安装事件过滤器,识别鼠标拖动和拉伸大小
- this->installEventFilter(this);
- //设置焦点策略,以便鼠标按下获取焦点并手柄可见
- this->setFocusPolicy(Qt::StrongFocus);
- }
- /// <summary>
- /// 拦截所属的控件事件
- /// </summary>
- /// <param name="watched"></param>
- /// <param name="event"></param>
- /// <returns></returns>
- bool SelectWidget::eventFilter(QObject *watched, QEvent *event)
- {
- // 拦截键盘事件
- if (event->type() == QEvent::KeyPress)
- {
- QKeyEvent *keyEvent = dynamic_cast<QKeyEvent *>(event);
- if (keyEvent->key() == Qt::Key_Left)
- {
- this->move(this->pos() - QPoint(1, 0));
- } else if (keyEvent->key() == Qt::Key_Right)
- {
- this->move(this->pos() + QPoint(1, 0));
- } else if (keyEvent->key() == Qt::Key_Up)
- {
- this->move(this->pos() - QPoint(0, 1));
- } else if (keyEvent->key() == Qt::Key_Down)
- {
- this->move(this->pos() + QPoint(0, 1));
- } else if (keyEvent->key() == Qt::Key_Delete)
- {
- emit widgetDelete(widget);
- widget->deleteLater();
- this->deleteLater();
- widget = 0;
- }
- //重新设置附带窗体的位置和大小
- if (widget != 0) {
- widget->setGeometry(this->x() + padding, this->y() + padding, this->width() - padding * 2, this->height() - padding * 2);
- }
- return QWidget::eventFilter(watched, event);
- }
- QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
- if (mouseEvent->type() == QEvent::MouseButtonPress)
- {
- //记住当前控件坐标和宽高以及鼠标按下的坐标
- rectX = this->x();
- rectY = this->y();
- rectW = this->width();
- rectH = this->height();
- lastPos = mouseEvent->pos();
- //判断按下的手柄的区域位置
- if (rectLeft.contains(lastPos)) {
- pressedLeft = true;
- } else if (rectRight.contains(lastPos)) {
- pressedRight = true;
- } else if (rectTop.contains(lastPos)) {
- pressedTop = true;
- } else if (rectBottom.contains(lastPos)) {
- pressedBottom = true;
- } else if (rectLeftTop.contains(lastPos)) {
- pressedLeftTop = true;
- } else if (rectRightTop.contains(lastPos)) {
- pressedRightTop = true;
- } else if (rectLeftBottom.contains(lastPos)) {
- pressedLeftBottom = true;
- } else if (rectRightBottom.contains(lastPos)) {
- pressedRightBottom = true;
- } else {
- pressed = true;
- }
- if (widget != 0)
- {
- emit widgetPressed(widget);
- }
- }
- else if (mouseEvent->type() == QEvent::MouseMove)
- {
- //根据当前鼠标位置,计算XY轴移动了多少
- QPoint pos = mouseEvent->pos();
- int dx = pos.x() - lastPos.x();
- int dy = pos.y() - lastPos.y();
- //根据按下处的位置判断是否是移动控件还是拉伸控件
- if (pressed)
- {
- this->move(this->x() + dx, this->y() + dy);
- }
- else if (pressedLeft)
- {
- int resizeW = this->width() - dx;
- if (this->minimumWidth() <= resizeW)
- {
- this->setGeometry(this->x() + dx, rectY, resizeW, rectH);
- }
- }
- else if (pressedRight)
- {
- this->setGeometry(rectX, rectY, rectW + dx, rectH);
- }
- else if (pressedTop)
- {
- int resizeH = this->height() - dy;
- if (this->minimumHeight() <= resizeH)
- {
- this->setGeometry(rectX, this->y() + dy, rectW, resizeH);
- }
- }
- else if (pressedBottom)
- {
- this->setGeometry(rectX, rectY, rectW, rectH + dy);
- }
- else if (pressedLeftTop)
- {
- int resizeW = this->width() - dx;
- int resizeH = this->height() - dy;
- if (this->minimumWidth() <= resizeW) {
- this->setGeometry(this->x() + dx, this->y(), resizeW, resizeH);
- }
- if (this->minimumHeight() <= resizeH) {
- this->setGeometry(this->x(), this->y() + dy, resizeW, resizeH);
- }
- }
- else if (pressedRightTop)
- {
- int resizeW = rectW + dx;
- int resizeH = this->height() - dy;
- if (this->minimumHeight() <= resizeH) {
- this->setGeometry(this->x(), this->y() + dy, resizeW, resizeH);
- }
- }
- else if (pressedLeftBottom)
- {
- int resizeW = this->width() - dx;
- int resizeH = rectH + dy;
- if (this->minimumWidth() <= resizeW) {
- this->setGeometry(this->x() + dx, this->y(), resizeW, resizeH);
- }
- if (this->minimumHeight() <= resizeH) {
- this->setGeometry(this->x(), this->y(), resizeW, resizeH);
- }
- }
- else if (pressedRightBottom)
- {
- int resizeW = rectW + dx;
- int resizeH = rectH + dy;
- this->setGeometry(this->x(), this->y(), resizeW, resizeH);
- }
- //重新设置附带窗体的位置和大小
- if (widget != 0)
- {
- widget->setGeometry(this->x() + padding, this->y() + padding, this->width() - padding * 2, this->height() - padding * 2);
- }
- // 2022-3-20修改,如果和上次的区域区域有变化,则发出控件移动信号,用于向属性表同步
-
- if( this->geometry()!= oldGeometry )
- {
- // emit widgetMove(widget);
- oldGeometry = this->geometry();
- }
- }
- else if (mouseEvent->type() == QEvent::MouseButtonRelease)
- {
- pressed = false;
- pressedLeft = false;
- pressedRight = false;
- pressedTop = false;
- pressedBottom = false;
- pressedLeftTop = false;
- pressedRightTop = false;
- pressedLeftBottom = false;
- pressedRightBottom = false;
- if (widget != 0)
- {
- emit widgetRelease(widget);
- }
- }
- return QWidget::eventFilter(watched, event);
- }
- void SelectWidget::resizeEvent(QResizeEvent *)
- {
- // qDebug() << "SelectWidget::resizeEvent";
- //重新计算八个描点的区域,描点区域的作用还有就是计算鼠标坐标是否在某一个区域内
- double width = this->width();
- double height = this->height();
- //左侧描点区域
- rectLeft = QRectF(0, int( height / 2.0 - pointSize / 2.0), pointSize, pointSize);
- //上侧描点区域
- rectTop = QRectF(int(width / 2 - pointSize / 2), 0, pointSize, pointSize);
- //右侧描点区域
- rectRight = QRectF(int(width - pointSize),int( height / 2 - pointSize / 2), pointSize, pointSize);
- //下侧描点区域
- rectBottom = QRectF(int(width / 2 - pointSize / 2), height - pointSize, pointSize, pointSize);
- //左上角描点区域
- rectLeftTop = QRectF(0, 0, pointSize, pointSize);
- //右上角描点区域
- rectRightTop = QRectF(int(width - pointSize), 0, pointSize, pointSize);
- //左下角描点区域
- rectLeftBottom = QRectF(0, int(height - pointSize), pointSize, pointSize);
- //右下角描点区域
- rectRightBottom = QRectF(width - pointSize, height - pointSize, pointSize, pointSize);
- }
- void SelectWidget::mouseMoveEvent(QMouseEvent *e)
- {
- // qDebug() << "SelectWidget::mouseMoveEvent";
- //计算当前鼠标位置是否在某个区域内,自动更新鼠标形状
- QPoint p = e->pos();
- if (rectLeft.contains(p)) {
- this->setCursor(Qt::SizeHorCursor);
- } else if (rectTop.contains(p)) {
- this->setCursor(Qt::SizeVerCursor);
- } else if (rectRight.contains(p)) {
- this->setCursor(Qt::SizeHorCursor);
- } else if (rectBottom.contains(p)) {
- this->setCursor(Qt::SizeVerCursor);
- } else if (rectLeftTop.contains(p)) {
- this->setCursor(Qt::SizeFDiagCursor);
- } else if (rectRightTop.contains(p)) {
- this->setCursor(Qt::SizeBDiagCursor);
- } else if (rectLeftBottom.contains(p)) {
- this->setCursor(Qt::SizeBDiagCursor);
- } else if (rectRightBottom.contains(p)) {
- this->setCursor(Qt::SizeFDiagCursor);
- } else {
- this->setCursor(Qt::ArrowCursor);
- }
- }
- void SelectWidget::paintEvent(QPaintEvent *)
- {
- if (!drawPoint) {
- return;
- }
- QPainter painter(this);
- painter.setRenderHints(QPainter::Antialiasing);
- painter.setPen(Qt::NoPen);
- painter.setBrush(pointColor);
- if (pointStyle == PointStyle::PointStyle_Rect)
- {
- drawRect(&painter);
- } else if (pointStyle == PointStyle:: PointStyle_Circle)
- {
- drawCircle(&painter);
- }
- if (borderWidth > 0)
- {
- drawBorder(&painter);
- }
- }
- void SelectWidget::drawRect(QPainter *painter)
- {
- //逐个绘制 左上角点+顶边中间点+右上角点+左边中间点+右边中间点+左下角点+底边中间点+右下角点
- painter->save();
- painter->drawRect(rectLeft);
- painter->drawRect(rectRight);
- painter->drawRect(rectTop);
- painter->drawRect(rectBottom);
- painter->drawRect(rectLeftTop);
- painter->drawRect(rectRightTop);
- painter->drawRect(rectLeftBottom);
- painter->drawRect(rectRightBottom);
- painter->restore();
- }
- void SelectWidget::drawCircle(QPainter *painter)
- {
- //逐个绘制 左上角点+顶边中间点+右上角点+左边中间点+右边中间点+左下角点+底边中间点+右下角点
- painter->save();
- painter->drawEllipse(rectLeft);
- painter->drawEllipse(rectRight);
- painter->drawEllipse(rectTop);
- painter->drawEllipse(rectBottom);
- painter->drawEllipse(rectLeftTop);
- painter->drawEllipse(rectRightTop);
- painter->drawEllipse(rectLeftBottom);
- painter->drawEllipse(rectRightBottom);
- painter->restore();
- }
- void SelectWidget::drawBorder(QPainter *painter)
- {
- painter->save();
- QPen pen;
- pen.setWidth(borderWidth);
- pen.setColor(pointColor);
- painter->setPen(pen);
- painter->setBrush(Qt::NoBrush);
- QRectF borderRect( int( pointSize / 2), int(pointSize / 2), int(width() - pointSize), int (height() - pointSize));
- painter->drawRect(borderRect);
- painter->restore();
- }
- bool SelectWidget::getDrawPoint() const
- {
- return this->drawPoint;
- }
- int SelectWidget::getPadding() const
- {
- return this->padding;
- }
- int SelectWidget::getBorderWidth() const
- {
- return this->borderWidth;
- }
- int SelectWidget::getPointSize() const
- {
- return this->pointSize;
- }
- QColor SelectWidget::getPointColor() const
- {
- return this->pointColor;
- }
- SelectWidget::PointStyle SelectWidget::getPointStyle() const
- {
- return this->pointStyle;
- }
- QWidget *SelectWidget::getWidget() const
- {
- return widget;
- }
- QSize SelectWidget::sizeHint() const
- {
- return QSize(200, 200);
- }
- QSize SelectWidget::minimumSizeHint() const
- {
- return QSize(30, 30);
- }
- void SelectWidget::setDrawPoint(bool drawPoint)
- {
- if (this->drawPoint != drawPoint) {
- this->drawPoint = drawPoint;
- update();
- }
- }
- void SelectWidget::setPadding(int padding)
- {
- if (this->padding != padding) {
- this->padding = padding;
- update();
- }
- }
- void SelectWidget::setBorderWidth(int borderWidth)
- {
- if (this->borderWidth != borderWidth) {
- this->borderWidth = borderWidth;
- update();
- }
- }
- void SelectWidget::setPointSize(int pointSize)
- {
- if (this->pointSize != pointSize) {
- this->pointSize = pointSize;
- update();
- }
- }
- void SelectWidget::setPointColor(const QColor &pointColor)
- {
- if (this->pointColor != pointColor) {
- this->pointColor = pointColor;
- update();
- }
- }
- void SelectWidget::setPointStyle(const SelectWidget::PointStyle &pointStyle)
- {
- if (this->pointStyle != pointStyle) {
- this->pointStyle = pointStyle;
- update();
- }
- }
- void SelectWidget::setWidget(QWidget *widget)
- {
- this->widget = widget;
- this->widget->setVisible(true);
- this->setVisible(true);
- //设置最小尺寸
- this->setMinimumSize(30, 30);
- //设置当前窗体大小为跟随窗体的大小增加部分
- this->resize(this->widget->size() + QSize(padding * 2, padding * 2));
- //将当前窗体移到偏移位置
- this->move(this->widget->pos() - QPoint(padding, padding));
- }
|