Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Make a frameless QWidget resizable with QRubberBand ?

Make a frameless QWidget resizable with QRubberBand ?

Scheduled Pinned Locked Moved Solved General and Desktop
qwidgetresizeframeless
19 Posts 3 Posters 14.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • IMAN4KI IMAN4K

    @mrjj
    Thanks for Attention.
    I get all you say and know what to do but :
    My Widget is actually a base Widget for a Custom Window so it has a Titlebar and i think eventFilter() is good. isn't it ?
    Another thing is about cursor changing.i need a space area (just say weight of 5) around my Widget so when Hover happen (and leave also) cursor must be change.
    How to achieve this?

    mrjjM Offline
    mrjjM Offline
    mrjj
    Lifetime Qt Champion
    wrote on last edited by
    #4

    @IMAN4K

    • and i think eventFilter() is good. isn't it ?
      Its fine and ok to use if u prefer over the mouseX methods.

    • .i need a space area (just say weight of 5) around my Widget

    One way to do this is via a layout. IF you add layout to window, and set
    contentsMargins u can get such free area.
    http://doc.qt.io/qt-5/qlayout.html#contentsMargins

    IMAN4KI 1 Reply Last reply
    1
    • mrjjM mrjj

      @IMAN4K

      • and i think eventFilter() is good. isn't it ?
        Its fine and ok to use if u prefer over the mouseX methods.

      • .i need a space area (just say weight of 5) around my Widget

      One way to do this is via a layout. IF you add layout to window, and set
      contentsMargins u can get such free area.
      http://doc.qt.io/qt-5/qlayout.html#contentsMargins

      IMAN4KI Offline
      IMAN4KI Offline
      IMAN4K
      wrote on last edited by
      #5

      @mrjj
      Is there another way for that area ?
      Because if i implement mouseX events for my Widget and if cursor change happen, all around my widget cursor stay the same and i need that changing just for that edge area

      mrjjM 1 Reply Last reply
      0
      • IMAN4KI IMAN4K

        @mrjj
        Is there another way for that area ?
        Because if i implement mouseX events for my Widget and if cursor change happen, all around my widget cursor stay the same and i need that changing just for that edge area

        mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by
        #6

        @IMAN4K
        Hi
        Im not sure of the issue
        if mouse goes into area, u set it, if it leaves are u reset.
        You can check in mouseMove if it leaves the area moving further into the widget.

        so im not sure what ", all around my widget cursor stay the same"
        means ?

        IMAN4KI 1 Reply Last reply
        1
        • mrjjM mrjj

          @IMAN4K
          Hi
          Im not sure of the issue
          if mouse goes into area, u set it, if it leaves are u reset.
          You can check in mouseMove if it leaves the area moving further into the widget.

          so im not sure what ", all around my widget cursor stay the same"
          means ?

          IMAN4KI Offline
          IMAN4KI Offline
          IMAN4K
          wrote on last edited by
          #7

          @mrjj said:

          One way to do this is via a layout. IF you add layout to window, and set
          contentsMargins u can get such free area

          I'm confusing about this solution.
          That require area i have mentioned must receivemouseEvents and you said you must set a Layout so Can Layouts receive mouseEvent ?

          @mrjj said:

          so im not sure what ", all around my widget cursor stay the same"
          means ?

          I mean if i implement mouseEvent for my widget after hovering cursor will change at the edge of my widget
          it's good but if keep moving to widget(not leave the widget area) cursor will stay the same and will not change while cursor must return to arrow state if it pass that weight (5)

          I hope i have been clear.

          mrjjM 1 Reply Last reply
          0
          • IMAN4KI IMAN4K

            @mrjj said:

            One way to do this is via a layout. IF you add layout to window, and set
            contentsMargins u can get such free area

            I'm confusing about this solution.
            That require area i have mentioned must receivemouseEvents and you said you must set a Layout so Can Layouts receive mouseEvent ?

            @mrjj said:

            so im not sure what ", all around my widget cursor stay the same"
            means ?

            I mean if i implement mouseEvent for my widget after hovering cursor will change at the edge of my widget
            it's good but if keep moving to widget(not leave the widget area) cursor will stay the same and will not change while cursor must return to arrow state if it pass that weight (5)

            I hope i have been clear.

            mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by
            #8

            @IMAN4K

            • Can Layouts receive mouseEvent ?
              They should go to the Window Widget. or class that handles the
              cursor change.

            • cursor must return to arrow state if it pass that weight (5)
              I guess detecting it by using mouseMove is too unreliable.

            have you check if
            http://doc.qt.io/qt-5/qwidget.html#leaveEvent
            could be used?

            1 Reply Last reply
            1
            • IMAN4KI Offline
              IMAN4KI Offline
              IMAN4K
              wrote on last edited by IMAN4K
              #9

              @mrjj
              I think i finally figured it out ;)
              But can you look at my code please :

              class Widget : public QWidget {
              	Q_OBJECT
              
              public:
              	explicit Widget();
              	~Widget();
              	void setBorderWidth(const qint16 &borderWidth);
              
              private:
              	enum Edge
              	{
              		None,
              		Top,
              		Bottom,
              		Left,
              		Right,
              		TopLeft,
              		TopRight,
              		BottomLeft,
              		BottomRight
              	};
              	QRubberBand *_rubberband;
              	bool _cursorchanged;
              	bool _leftButtonPressed;
              	qint16 _borderWidth;
              	Edge _edge;
              
              private:
              	void mouseHover(QHoverEvent *e);
              	void mouseLeave(QEvent *e);
              	void mousePress(QMouseEvent *e);
              	void mouseRealese(QMouseEvent *e);
              	void mouseMove(QMouseEvent *e);
              	void updateCursorShape(const QPoint &pos);
              	void calculateCursorPosition(const QPoint &pos);
              	void updateRubberBand();
              
              protected:
              	void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
              	bool eventFilter(QObject *o, QEvent *e) Q_DECL_OVERRIDE;
              };
              
              Widget::Widget() :
              _cursorchanged(false),
              _borderWidth(4),
              _edge(None),
              _leftButtonPressed(false),
              _rubberband(0)
              {
              	setMouseTracking(true);
              	setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint);
              	setAttribute(Qt::WA_Hover);
              	setAttribute(Qt::WA_TranslucentBackground);
              	installEventFilter(this);
              }
              
              Widget::~Widget() {}
              
              void Widget::paintEvent(QPaintEvent *) {
              	QPainter painter(this);
              	painter.setBrush(QColor("#FFFFFF"));
              	painter.setPen(Qt::NoPen);
              	painter.setRenderHint(QPainter::Antialiasing);
              
              	QPainterPath path;
              	path.addRoundedRect(QRect(0, 0, width(), height()), 5.0, 5.0);
              	painter.drawPath(path.simplified());
              }
              
              bool Widget::eventFilter(QObject *o, QEvent*e) {
              	if (e->type() == QEvent::MouseMove ||
              		e->type() == QEvent::HoverMove ||
              		e->type() == QEvent::Leave ||
              		e->type() == QEvent::MouseButtonPress ||
              		e->type() == QEvent::MouseButtonRelease) {
              
              		switch (e->type())
              		{
              		default:
              			break;
              		case QEvent::MouseMove:
              			mouseMove(static_cast<QMouseEvent*>(e));
              			break;
              		case QEvent::HoverMove:
              			mouseHover(static_cast<QHoverEvent*>(e));
              			break;
              		case QEvent::Leave:
              			mouseLeave(e);
              			break;
              		case QEvent::MouseButtonPress:
              			mousePress(static_cast<QMouseEvent*>(e));
              			break;
              		case QEvent::MouseButtonRelease:
              			mouseRealese(static_cast<QMouseEvent*>(e));
              			break;
              		}
              	}
              	return false;
              }
              
              void Widget::mouseHover(QHoverEvent *e) {
              	updateCursorShape(mapToGlobal(e->pos()));
              
              }
              
              void Widget::mouseLeave(QEvent *e) {
              	Q_UNUSED(e);
              	unsetCursor();
              }
              
              void Widget::mousePress(QMouseEvent *e) {
              	if (e->buttons() && Qt::LeftButton) {
              		_leftButtonPressed = true;
              		if (_edge != None) {
              			updateRubberBand();
              			_rubberband->setGeometry(frameGeometry().x(), frameGeometry().y(), frameGeometry().width(), frameGeometry().height());
              		}
              	}
              }
              
              void Widget::mouseRealese(QMouseEvent *e) {
              		_leftButtonPressed = false;
              		_edge = None;
              		if (_rubberband) {
              			updateRubberBand();
              		}
              }
              
              void Widget::mouseMove(QMouseEvent *e) {
              	if (_leftButtonPressed && _edge != None) {
              		QRect originalRect = _rubberband->frameGeometry();
              		int left = originalRect.left();
              		int top = originalRect.top();
              		int right = originalRect.right();
              		int bottom = originalRect.bottom();
              		if (_edge == Top) {
              			top = e->globalPos().y();
              		} else if (_edge == Bottom) {
              			bottom = e->globalPos().y();
              		} else if (_edge == Left) {
              			left = e->globalPos().x();
              		} else if (_edge == Right) {
              			right = e->globalPos().x();
              		} else if (_edge == TopLeft) {
              			left = e->globalPos().x();
              			top = e->globalPos().y();
              		} else if (_edge == TopRight) {
              			top = e->globalPos().y();
              			right = e->globalPos().x();
              		} else if (_edge == BottomLeft) {
              			left = e->globalPos().x();
              			bottom = e->globalPos().y();
              		} else if (_edge == BottomRight) {
              			bottom = e->globalPos().y();
              			right = e->globalPos().x();
              		}
              		_rubberband->setGeometry(QRect(QPoint(left, top), QPoint(right, bottom)));
              		setGeometry(_rubberband->geometry());
              	}
              }
              
              void Widget::updateCursorShape(const QPoint &pos) {
              	if (isFullScreen() || isMaximized()) { 
              		if (_cursorchanged) {
              			unsetCursor();
              			return;
              		}
              	}
              	calculateCursorPosition((pos));
              	if (_edge == TopLeft || _edge == BottomRight) {
              		setCursor(Qt::SizeFDiagCursor);
              		_cursorchanged = true;
              	} else if (_edge == TopRight || _edge == BottomLeft) {
              		setCursor(Qt::SizeBDiagCursor);
              		_cursorchanged = true;
              	} else if (_edge == Right || _edge == Left) {
              		setCursor(Qt::SizeHorCursor);
              		_cursorchanged = true;
              	} else if (_edge == Top || _edge == Bottom) {
              		setCursor(Qt::SizeVerCursor);
              		_cursorchanged = true;
              	} else if (_cursorchanged) {
              		_cursorchanged = false;
              		unsetCursor();
              	}
              	
              }
              
              void Widget::calculateCursorPosition(const QPoint &pos) {
              	bool onLeft = pos.x() <= frameGeometry().x() + _borderWidth && pos.x() >= frameGeometry().x() &&
              		pos.y() <= frameGeometry().y() + frameGeometry().height() - _borderWidth && pos.y() >= frameGeometry().y() + _borderWidth;
              
              	bool onRight = pos.x() >= frameGeometry().x() + frameGeometry().width() - _borderWidth && pos.x() <= frameGeometry().x() + frameGeometry().width() &&
              		pos.y() >= frameGeometry().y() + _borderWidth && pos.y() <= frameGeometry().y() + frameGeometry().height() - _borderWidth - 2;
              
              	bool onBottom = pos.x() >= frameGeometry().x() + _borderWidth && pos.x() <= frameGeometry().x() + frameGeometry().width() - _borderWidth - 2 &&
              		pos.y() >= frameGeometry().y() + frameGeometry().height() - _borderWidth && pos.y() <= frameGeometry().y() + frameGeometry().height();
              
              	bool onTop = pos.x() >= frameGeometry().x() + _borderWidth && pos.x() <= frameGeometry().x() + frameGeometry().width() - _borderWidth &&
              		pos.y() >= frameGeometry().y() && pos.y() <= frameGeometry().y() + _borderWidth;
              
              	bool  onBottomleft = pos.x() <= frameGeometry().x() + _borderWidth && pos.x() >= frameGeometry().x() &&
              		pos.y() <= frameGeometry().y() + frameGeometry().height() && pos.y() >= frameGeometry().y() + frameGeometry().height() - _borderWidth;
              
              	bool onBottomRight = pos.x() >= frameGeometry().x() + frameGeometry().width() - _borderWidth && pos.x() <= frameGeometry().x() + frameGeometry().width() &&
              		pos.y() >= frameGeometry().y() + frameGeometry().height() - _borderWidth && pos.y() <= frameGeometry().y() + frameGeometry().height();
              
              	bool onTopRight = pos.x() >= frameGeometry().x() + frameGeometry().width() - _borderWidth && pos.x() <= frameGeometry().x() + frameGeometry().width() &&
              		pos.y() >= frameGeometry().y() && pos.y() <= frameGeometry().y() + _borderWidth;
              
              	bool onTopLeft = pos.x() >= frameGeometry().x() && pos.x() <= frameGeometry().x() + _borderWidth &&
              		pos.y() >= frameGeometry().y() && pos.y() <= frameGeometry().y() + _borderWidth;
              
                  if (onLeft) {
              		_edge = Left;
              	} else if (onRight) {
              		_edge = Right;
              	} else if (onBottom) {
              		_edge = Bottom;
              	} else if (onTop) {
              		_edge = Top;
              	} else if (onBottomleft) {
              		_edge = BottomLeft;
              	} else if (onBottomRight) {
              		_edge = BottomRight;
              	} else if (onTopRight) {
              		_edge = TopRight;
              	} else if (onTopLeft) {
              		_edge = TopLeft;
              	} else {
              		_edge = None;
              	}
              }
              
              void Widget::updateRubberBand() {
              	if (!_rubberband) {
              		_rubberband = new QRubberBand(QRubberBand::Rectangle);
              	} else {
              		delete _rubberband;
              		_rubberband = 0;
              	}
              }
              
              void Widget::setBorderWidth(const qint16 &borderWidth) {
              	_borderWidth = borderWidth;
              }
              

              It work but for top edge and left edge it's not working as i expect !

              1 Reply Last reply
              2
              • mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by
                #10

                Hi
                Good work.
                So for top/left what happens?

                IMAN4KI 1 Reply Last reply
                1
                • mrjjM mrjj

                  Hi
                  Good work.
                  So for top/left what happens?

                  IMAN4KI Offline
                  IMAN4KI Offline
                  IMAN4K
                  wrote on last edited by
                  #11

                  @mrjj
                  It doesn't extend the widget from the top and left edge (+bottomLeft+topLeft+topRight) and i have no idea !
                  https://drive.google.com/file/d/0BxRSkzkLrTjVX18wd0U4YWZnVms/view?pref=2&pli=1
                  Thanks for your time.

                  1 Reply Last reply
                  0
                  • mrjjM Offline
                    mrjjM Offline
                    mrjj
                    Lifetime Qt Champion
                    wrote on last edited by
                    #12

                    Ok
                    First. good job. Seem to work great.
                    I can see that dragging up seems not to work but
                    did not spot anything looking at code.

                    Is the code complete?
                    I can run it if I put in a default project?

                    IMAN4KI 1 Reply Last reply
                    1
                    • mrjjM mrjj

                      Ok
                      First. good job. Seem to work great.
                      I can see that dragging up seems not to work but
                      did not spot anything looking at code.

                      Is the code complete?
                      I can run it if I put in a default project?

                      IMAN4KI Offline
                      IMAN4KI Offline
                      IMAN4K
                      wrote on last edited by IMAN4K
                      #13

                      @mrjj

                      Is the code complete?

                      Yes It's complete

                      mrjjM 1 Reply Last reply
                      0
                      • IMAN4KI IMAN4K

                        @mrjj

                        Is the code complete?

                        Yes It's complete

                        mrjjM Offline
                        mrjjM Offline
                        mrjj
                        Lifetime Qt Champion
                        wrote on last edited by
                        #14

                        @IMAN4K
                        Yep. Besides some #include it ran.

                        The reason up dont work is that it adjust the window the wrong way
                        (y++) so when u drag up, it goes down 1 pixel and then mouse is outside and the drag stops.

                        Not sure where the actual error is yet. Seems to be need minus and not plus
                        for drag that way.

                        IMAN4KI 1 Reply Last reply
                        1
                        • mrjjM mrjj

                          @IMAN4K
                          Yep. Besides some #include it ran.

                          The reason up dont work is that it adjust the window the wrong way
                          (y++) so when u drag up, it goes down 1 pixel and then mouse is outside and the drag stops.

                          Not sure where the actual error is yet. Seems to be need minus and not plus
                          for drag that way.

                          IMAN4KI Offline
                          IMAN4KI Offline
                          IMAN4K
                          wrote on last edited by
                          #15

                          @mrjj
                          Still no idea ?
                          I'm really stuck !

                          mrjjM 1 Reply Last reply
                          0
                          • IMAN4KI IMAN4K

                            @mrjj
                            Still no idea ?
                            I'm really stuck !

                            mrjjM Offline
                            mrjjM Offline
                            mrjj
                            Lifetime Qt Champion
                            wrote on last edited by
                            #16

                            @IMAN4K
                            Sorry. nope.
                            Nothing jumped to mind.

                            Did you qDebug the points used for adjusting Geometry ?
                            To see how values are when is the Top case?

                            1 Reply Last reply
                            2
                            • IMAN4KI Offline
                              IMAN4KI Offline
                              IMAN4K
                              wrote on last edited by IMAN4K
                              #17

                              Thanks @mrjj for all answers.
                              You were right calculating was mistake
                              I just used an inner space for calculating mouse area but you also need to consider an outer area (the green border) :
                              https://onedrive.live.com/redir?resid=8882D1E3BC0F61AB!7402&authkey=!ACT6umOQeAEcN7A&v=3&ithint=photo%2Cjpg
                              Here for any one else :

                              frameless.h:

                              #include <QtWidgets/QWidget>
                              #include <QtWidgets/QRubberBand>
                              #include <QtCore/QObject>
                              #include <QtCore/QEvent>
                              #include <QtCore/QRect>
                              #include <QtCore/QPoint>
                              #include <QtCore/Qt>
                              #include <QtGui/QHoverEvent>
                              #include <QtGui/QMouseEvent>
                              
                              class FrameLess : public QObject {
                              public:
                              	enum Edge {
                              		None = 0x0,
                              		Left = 0x1,
                              		Top = 0x2,
                              		Right = 0x4,
                              		Bottom = 0x8,
                              		TopLeft = 0x10,
                              		TopRight = 0x20,
                              		BottomLeft = 0x40,
                              		BottomRight = 0x80,
                              	};
                              	Q_ENUM(Edge);
                              	Q_DECLARE_FLAGS(Edges, Edge);
                              
                              	FrameLess(QWidget *parent);
                              
                              	void setBorderWidth(int);
                              	int borderWidth() const;
                              
                              	QWidget *_parent = nullptr;
                              	QRubberBand *_rubberband = nullptr;
                              	bool _cursorchanged;
                              	bool _leftButtonPressed;
                              	Edges _mousePress = Edge::None;
                              	Edges _mouseMove = Edge::None;
                              	int _borderWidth;
                              
                              	QPoint _dragPos;
                              	bool _dragStart = false;
                              
                              protected:
                              	bool eventFilter(QObject *o, QEvent *e) override;
                              	void mouseHover(QHoverEvent*);
                              	void mouseLeave(QEvent*);
                              	void mousePress(QMouseEvent*);
                              	void mouseRealese(QMouseEvent*);
                              	void mouseMove(QMouseEvent*);
                              	void updateCursorShape(const QPoint &);
                              	void calculateCursorPosition(const QPoint &, const QRect &, Edges &);
                              };
                              
                              Q_DECLARE_OPERATORS_FOR_FLAGS(FrameLess::Edges);
                              

                              frameless.cpp:

                              #include "FrameLess.h"
                              
                              FrameLess::FrameLess(QWidget *parent) :
                              _parent(parent),
                              _cursorchanged(false),
                              _leftButtonPressed(false),
                              _borderWidth(5),
                              _dragPos(QPoint())
                              {
                              	_parent->setMouseTracking(true);
                              	_parent->setWindowFlags(Qt::FramelessWindowHint);
                              	_parent->setAttribute(Qt::WA_Hover);
                              	_parent->installEventFilter(this);
                              	_rubberband = new QRubberBand(QRubberBand::Rectangle);
                              }
                              
                              bool FrameLess::eventFilter(QObject *o, QEvent*e) {
                              	if (e->type() == QEvent::MouseMove ||
                              		e->type() == QEvent::HoverMove ||
                              		e->type() == QEvent::Leave ||
                              		e->type() == QEvent::MouseButtonPress ||
                              		e->type() == QEvent::MouseButtonRelease) {
                              
                              		switch (e->type()) {
                              		case QEvent::MouseMove:
                              			mouseMove(static_cast<QMouseEvent*>(e));
                              			return true;
                              			break;
                              		case QEvent::HoverMove:
                              			mouseHover(static_cast<QHoverEvent*>(e));
                              			return true;
                              			break;
                              		case QEvent::Leave:
                              			mouseLeave(e);
                              			return true;
                              			break;
                              		case QEvent::MouseButtonPress:
                              			mousePress(static_cast<QMouseEvent*>(e));
                              			return true;
                              			break;
                              		case QEvent::MouseButtonRelease:
                              			mouseRealese(static_cast<QMouseEvent*>(e));
                              			return true;
                              			break;
                              		}
                              	} else {
                              		return _parent->eventFilter(o, e);
                              	}
                              }
                              
                              void FrameLess::mouseHover(QHoverEvent *e) {
                              	updateCursorShape(_parent->mapToGlobal(e->pos()));
                              }
                              
                              void FrameLess::mouseLeave(QEvent *e) {
                              	if (!_leftButtonPressed) {
                              		_parent->unsetCursor();
                              	}
                              }
                              
                              void FrameLess::mousePress(QMouseEvent *e) {
                              	if (e->button() & Qt::LeftButton) {
                              		_leftButtonPressed = true;
                              		calculateCursorPosition(e->globalPos(), _parent->frameGeometry(), _mousePress);
                              		if (!_mousePress.testFlag(Edge::None)) {
                              			_rubberband->setGeometry(_parent->frameGeometry());
                              		}
                              		if (_parent->rect().marginsRemoved(QMargins(borderWidth(),borderWidth(),borderWidth(),borderWidth())).contains(e->pos())) {
                              			_dragStart = true;
                              			_dragPos = e->pos();
                              		}
                              	}
                              }
                              
                              void FrameLess::mouseRealese(QMouseEvent *e) {
                              	if (e->button() & Qt::LeftButton) {
                              		_leftButtonPressed = false;
                              		_dragStart = false;
                              	}
                              }
                              
                              void FrameLess::mouseMove(QMouseEvent *e) {
                              	if (_leftButtonPressed) {
                              		if (_dragStart) {
                              			_parent->move(_parent->frameGeometry().topLeft() + (e->pos() - _dragPos));
                              		}
                              
                              		if (!_mousePress.testFlag(Edge::None)) {
                              			int left = _rubberband->frameGeometry().left();
                              			int top = _rubberband->frameGeometry().top();
                              			int right = _rubberband->frameGeometry().right();
                              			int bottom = _rubberband->frameGeometry().bottom();
                              			switch (_mousePress) {
                              			case Edge::Top:
                              				top = e->globalPos().y();
                              				break;
                              			case Edge::Bottom:
                              				bottom = e->globalPos().y();
                              				break;
                              			case Edge::Left:
                              				left = e->globalPos().x();
                              				break;
                              			case Edge::Right:
                              				right = e->globalPos().x();
                              				break;
                              			case Edge::TopLeft:
                              				top = e->globalPos().y();
                              				left = e->globalPos().x();
                              				break;
                              			case Edge::TopRight:
                              				right = e->globalPos().x();
                              				top = e->globalPos().y();
                              				break;
                              			case Edge::BottomLeft:
                              				bottom = e->globalPos().y();
                              				left = e->globalPos().x();
                              				break;
                              			case Edge::BottomRight:
                              				bottom = e->globalPos().y();
                              				right = e->globalPos().x();
                              				break;
                              			}
                              			QRect newRect(QPoint(left, top), QPoint(right, bottom));
                              			if (newRect.width() < _parent->minimumWidth()) {
                              				left = _parent->frameGeometry().x();
                              			} else if (newRect.height() < _parent->minimumHeight()) {
                              				top = _parent->frameGeometry().y();
                              			}
                              			_parent->setGeometry(QRect(QPoint(left, top), QPoint(right, bottom)));
                              			_rubberband->setGeometry(QRect(QPoint(left, top), QPoint(right, bottom)));
                              		}
                              	} else {
                              		updateCursorShape(e->globalPos());
                              	}
                              }
                              
                              void FrameLess::updateCursorShape(const QPoint &pos) {
                              	if (_parent->isFullScreen() || _parent->isMaximized()) {
                              		if (_cursorchanged) {
                              			_parent->unsetCursor();
                              		}
                              		return;
                              	}
                              	if (!_leftButtonPressed) {
                              		calculateCursorPosition(pos, _parent->frameGeometry(), _mouseMove);
                              		_cursorchanged = true;
                              		if (_mouseMove.testFlag(Edge::Top) || _mouseMove.testFlag(Edge::Bottom)) {
                              			_parent->setCursor(Qt::SizeVerCursor);
                              		} else if (_mouseMove.testFlag(Edge::Left) || _mouseMove.testFlag(Edge::Right)) {
                              			_parent->setCursor(Qt::SizeHorCursor);
                              		} else if (_mouseMove.testFlag(Edge::TopLeft) || _mouseMove.testFlag(Edge::BottomRight)) {
                              			_parent->setCursor(Qt::SizeFDiagCursor);
                              		} else if (_mouseMove.testFlag(Edge::TopRight) || _mouseMove.testFlag(Edge::BottomLeft)) {
                              			_parent->setCursor(Qt::SizeBDiagCursor);
                              		} else if (_cursorchanged) {
                              			_parent->unsetCursor();
                              			_cursorchanged = false;
                              		}
                              	}
                              }
                              
                              void FrameLess::calculateCursorPosition(const QPoint &pos, const QRect &framerect, Edges &_edge) {
                              	bool onLeft = pos.x() >= framerect.x() - _borderWidth && pos.x() <= framerect.x() + _borderWidth &&
                              		pos.y() <= framerect.y() + framerect.height() - _borderWidth && pos.y() >= framerect.y() + _borderWidth;
                              
                              	bool onRight = pos.x() >= framerect.x() + framerect.width() - _borderWidth && pos.x() <= framerect.x() + framerect.width() &&
                              		pos.y() >= framerect.y() + _borderWidth && pos.y() <= framerect.y() + framerect.height() - _borderWidth;
                              
                              	bool onBottom = pos.x() >= framerect.x() + _borderWidth && pos.x() <= framerect.x() + framerect.width() - _borderWidth  &&
                              		pos.y() >= framerect.y() + framerect.height() - _borderWidth && pos.y() <= framerect.y() + framerect.height();
                              
                              	bool onTop = pos.x() >= framerect.x() + _borderWidth && pos.x() <= framerect.x() + framerect.width() - _borderWidth &&
                              		pos.y() >= framerect.y() && pos.y() <= framerect.y() + _borderWidth;
                              
                              	bool  onBottomLeft = pos.x() <= framerect.x() + _borderWidth && pos.x() >= framerect.x() &&
                              		pos.y() <= framerect.y() + framerect.height() && pos.y() >= framerect.y() + framerect.height() - _borderWidth;
                              
                              	bool onBottomRight = pos.x() >= framerect.x() + framerect.width() - _borderWidth && pos.x() <= framerect.x() + framerect.width() &&
                              		pos.y() >= framerect.y() + framerect.height() - _borderWidth && pos.y() <= framerect.y() + framerect.height();
                              
                              	bool onTopRight = pos.x() >= framerect.x() + framerect.width() - _borderWidth && pos.x() <= framerect.x() + framerect.width() &&
                              		pos.y() >= framerect.y() && pos.y() <= framerect.y() + _borderWidth;
                              
                              	bool onTopLeft = pos.x() >= framerect.x() && pos.x() <= framerect.x() + _borderWidth &&
                              		pos.y() >= framerect.y() && pos.y() <= framerect.y() + _borderWidth;
                              
                              	if (onLeft) {
                              		_edge = Left;
                              	} else if (onRight) {
                              		_edge = Right;
                              	} else if (onBottom) {
                              		_edge = Bottom;
                              	} else if (onTop) {
                              		_edge = Top;
                              	} else if (onBottomLeft) {
                              		_edge = BottomLeft;
                              	} else if (onBottomRight) {
                              		_edge = BottomRight;
                              	} else if (onTopRight) {
                              		_edge = TopRight;
                              	} else if (onTopLeft) {
                              		_edge = TopLeft;
                              	} else {
                              		_edge = None;
                              	}
                              }
                              
                              void FrameLess::setBorderWidth(int borderWidth) {
                              	_borderWidth = borderWidth;
                              }
                              
                              int FrameLess::borderWidth() const {
                              	return _borderWidth;
                              }
                              
                              1 Reply Last reply
                              1
                              • mrjjM Offline
                                mrjjM Offline
                                mrjj
                                Lifetime Qt Champion
                                wrote on last edited by
                                #18

                                Good found.
                                Thx for reporting back.
                                Im sure someone will re-use this some day.

                                1 Reply Last reply
                                0
                                • W Offline
                                  W Offline
                                  wrekler
                                  wrote on last edited by
                                  #19

                                  I found very usefull this class, I added some code to handle correctly a maximized FrameLess Widget.
                                  In

                                  void FrameLess::mouseMove(QMouseEvent *e) {
                                  	if (_dragStart) {
                                  		if (_parent->isMaximized()) { //this will handle correctly dragging when it is maximized
                                  			maximizeWidth = _parent->width(); //maximizeWidth is an int attribute
                                  			_parent->showNormal();
                                  		}
                                  		if (_dragPos.x() > _parent->width())
                                  			_dragPos.setX((_parent->width()*_dragPos.x()) / maximizeWidth);
                                  		_parent->move(e->globalX() - _dragPos.x(), e->globalY() - _dragPos.y());
                                  	}
                                  	if (!_mousePress.testFlag(Edge::None) && !_parent->isMaximized() ) { //this prevent resizing if it is maximized
                                  		[...]
                                  

                                  Now I'm wondering if there is a way to implement Windows 7/10 autosize function (the function when you drag a window on top/left/right/bottom edge of desktop and it will maximize/resize to half desktop size) on a frameless widget!

                                  1 Reply Last reply
                                  1

                                  • Login

                                  • Login or register to search.
                                  • First post
                                    Last post
                                  0
                                  • Categories
                                  • Recent
                                  • Tags
                                  • Popular
                                  • Users
                                  • Groups
                                  • Search
                                  • Get Qt Extensions
                                  • Unsolved