Window resizing on top & left gliching out,



  • Hello!

    I am trying to add the ability to resize to my boarderless QMainWindow. With myself and several other people(Thanks francescmm), it is almost complete. However, I am having trouble resizeing the top and left sides of the window.

    It is more tricky than the other sides because it is a resize coupled with a move, since resizing a windows does not change it's position.

    Currently, my code is unhappy with those sides, when I try to resize those sides, the window window resizes along the axis you select erratically, getting larger on both sides of the window at a crazy rate until it starts returning memory errors saying it can't store the dimensions window this size and eventually crashes.

    I don't want to span this post with a lot of unrelated code, so I will add as little code as I can, so please ask for mode code if you need it.

    I would really appreciate if you could explain why my code is not working correctly. Thanks for all of the help!

    Context: The resize code is stored in a function called resizeWindow. It is called when mouseMoveEvent detects the mouse above the boarder. allowToResize is set to true when I click and am in the resize zone.

    This peice of the code shows the resizeing of the vertical and horizontal sides, the top vertical and left horizontal is the one I am having trouble with.

    @void mainTrackbox::resizeWindow(QMouseEvent *e)
    {
    if (allowToResize)
    {
    int xMouse = e->pos().x();
    int yMouse = e->pos().y();
    int wWidth = geometry().width();
    int wHeight = geometry().height();

        if (cursor().shape() == Qt::SizeVerCursor)
        {
            if (resizeVerTop)
            {
                int newY = geometry().y() + yMouse;
                int newHeight = wHeight - yMouse;
    
                if (newHeight > minimumSizeHint().height())
                {
                    resize(wWidth, newHeight);
                    move(geometry().x(), newY);
                }
            }
            else
                resize(wWidth, yMouse+1);
        }
        else if (cursor().shape() == Qt::SizeHorCursor)
        {
            if (resizeHorLeft)
            {
                int newX = geometry().x() + xMouse;
                int newWidth = wWidth - xMouse;
    
                if (newWidth > minimumSizeHint().width())
                {
                    resize(newWidth, wHeight);
                    move(newX, geometry().y());
                }
            }
            else
                resize(xMouse, wHeight);
        }
    

    //The Code Continues to resize on the diagonals, which are also gliching out on the top left and right and bootom right.@


  • Moderators

    what exactly do you mean with "glitching out"?

    Whatever it is :) maybe it's happening because you use the current cursor shape to identify the resize direction. You should create an enum with all 8 (+1 idle value) directions and determine the direction on the mouse press event and save it to a class member. In the mousemove event handlers then just use the local member instead. In the mouse release event handler reset it to idle value.

    I think the code also gets simplified when you just modify the geometry of the widget. Then you don't need to worry about moving and resizing. E.g. you just need to add the relative moving point to the top left of the current geometry.

    Something like the following. But if you are more comfortable with the current way it's also fine.
    @
    QRect geom = this->geometry();
    switch( m_ResizeDirection )
    {
    case ResizingTopLeft:
    geom.setTopLeft( geom.topLeft() + diffPoint );
    break;
    ....
    }
    this->setGeometry( geom );
    @



  • By gliching out I mean:

    Currently, my code is unhappy with those sides, when I try to resize those sides, the window window resizes along the axis you select erratically, getting larger on both sides of the window at a crazy rate until it starts returning memory errors saying it can’t store the dimensions window this size and eventually crashes.



  • I tried useing your code but am running into a strange question, someithing I also posting it as a new topic.

    Here it is:

    I am working to resize a boarderless window in qt, but I am having a strange problem, when I try to resize on the top and the left of the window, my mouse movement is scaled down and movement is very jittery. On the bottom and right, it behaves as expected with normal resizes. I am pretty sure there is a logic error in my code but can't figure out after two days of contemplating figure it out. I write this with qt and c++ but is fairly simple and should be readable to anyone who understands c style computer code.

    My code works by setting a enum of possible sides the mouse can be over, set when the mouse moves over them. When the mouse moves over the edge, the code calls resizeWindow and sets in resize zone to true. When I click the mouse, the mouse sets the coordinates of the press and sets the variable allowToResize to true. When the time comes to resize, the code subtracts the current mouse position from the position of the click position, adds it to the side of the rectangle that you are resizing, and then resets the originional click position with the current clikc position

    I would greatly appreaciate it if anyone can figure out what I overlooked in the code that causes it to behave correctly on some sides and scaled down on the top and left. If you need more of my code just let me know and I will post it. Thanks!!!

    Here is my code:

    @//called when mouse is pressed
    void mainTrackbox::mousePressEvent(QMouseEvent *e)
    {
    if (e->button() == Qt::LeftButton)
    {
    if (inResizeZone)
    {
    offset = e->pos();
    allowToResize = true;
    }
    }
    e->accept();
    }

    //Called when mouse is released
    void mainTrackbox::mouseReleaseEvent(QMouseEvent *e)
    {
    moveWidget = false;
    allowToResize = false;
    resizeDir = none;
    offset = QPoint();

    e->accept();
    

    }

    //Called when mouse is over resize zone, enum set when mouse moves over resize zone as well
    void mainTrackbox::resizeWindow(QMouseEvent *e)
    {
    if(allowToResize) {
    QPoint eventPoint = e->pos();
    QRect geom = this->geometry();
    QPoint diff = eventPoint - offset;

        qDebug() << eventPoint;
        qDebug() << offset;
        qDebug() << diff;
    
        switch (resizeDir) {
        default:
            break;
        case none:
            qDebug() <<"None";
            break;
        case top:
            qDebug() <<  geom.top();
            geom.setTop(geom.top() + diff.y());
            qDebug() <<  geom.top();
            qDebug() <<"Top";
            break;
        case bottom:
            qDebug() <<"Bottom";
            geom.setBottom(geom.bottom() + diff.y());
            break;
        case left:
            qDebug() <<"Left";
            geom.setLeft(geom.left() + diff.x());
            break;
        case right:
            qDebug() <<"Right";
            geom.setRight(geom.right() + diff.x());
            break;
        }
        this->setGeometry(geom);
        offset = eventPoint;
    }
    

    }@


  • Moderators

    try this:

    header:
    @
    class MyResizeableWidget : public QWidget
    {
    Q_OBJECT

    public:
    MyResizeableWidget(QWidget *parent = 0);

    enum ResizeState {
        IdleResize, TopResize, BottomResize, LeftResize, RightResize
    };
    

    protected:
    virtual void mousePressEvent(QMouseEvent *e);
    virtual void mouseMoveEvent(QMouseEvent *e);
    virtual void mouseReleaseEvent(QMouseEvent *e);

    ResizeState getResizeState(const QPoint & pos) const;
    
    ResizeState m_ResizeState;
    QPoint  m_ResizeOffset;
    

    };
    @

    cpp:
    @
    MyResizeableWidget::MyResizeableWidget(QWidget *parent) :
    QWidget(parent)
    {
    this->setWindowFlags( Qt::FramelessWindowHint );
    this->setMinimumSize(150,150);
    this->setMouseTracking(true);
    }

    void MyResizeableWidget::mousePressEvent(QMouseEvent *e)
    {
    if (e->button() == Qt::LeftButton)
    {
    m_ResizeState = this->getResizeState(e->pos());
    m_ResizeOffset = e->globalPos();
    }
    e->accept();
    }

    void MyResizeableWidget::mouseMoveEvent(QMouseEvent *e)
    {
    QPoint eventPoint = e->globalPos();
    QRect geom = this->geometry();
    QPoint diff = eventPoint - m_ResizeOffset;

    switch (m_ResizeState)
    {
    default:
        break;
    case TopResize:
        geom.setTop(geom.top() + diff.y());
        break;
    case BottomResize:
        geom.setBottom(geom.bottom() + diff.y());
        break;
    case LeftResize:
        geom.setLeft(geom.left() + diff.x());
        break;
    case RightResize:
        geom.setRight(geom.right() + diff.x());
        break;
    case IdleResize:
        {
            switch( this->getResizeState(e->pos()) )
            {
            case TopResize:
            case BottomResize:
                this->setCursor(Qt::SizeVerCursor);
                break;
            case LeftResize:
            case RightResize:
                this->setCursor(Qt::SizeHorCursor);
                break;
            case IdleResize:
            default:
                this->unsetCursor();
                break;
            }
        }
        break;
    }
    
    //do some checks
    if( geom.size().boundedTo(this->maximumSize()).expandedTo(this->minimumSize()) == geom.size() )
    {
        this->setGeometry(geom);
        m_ResizeOffset = eventPoint;
    }
    

    }

    void MyResizeableWidget::mouseReleaseEvent(QMouseEvent *e)
    {
    m_ResizeState = IdleResize;
    this->unsetCursor();
    e->accept();
    }

    MyResizeableWidget::ResizeState MyResizeableWidget::getResizeState(const QPoint &pos) const
    {
    int resizeMargin = 10;
    QRect r = this->rect();

    if( QRect(r.topLeft(),QPoint(r.right(),r.top()+resizeMargin)).contains(pos) )
        return TopResize;
    else if( QRect(QPoint(r.left(),r.bottom()-resizeMargin),r.bottomRight()).contains(pos) )
        return BottomResize;
    else if( QRect(QPoint(r.right()-resizeMargin,r.top()),r.bottomRight()).contains(pos) )
        return RightResize;
    else if( QRect(r.topLeft(),QPoint(r.left()+resizeMargin,r.bottom())).contains(pos) )
        return LeftResize;
    else
        return IdleResize;
    

    }
    @



  • Cool! On my computer, the resize works but is still a little jittery on the top and left, is there anything I can do about that?


  • Moderators

    as i "said":http://qt-project.org/forums/viewthread/31517/#138970 in your other thread: no.



  • Thanks for all of the help. Do you recommend any other way to go about hiding or removing the window frame that would work better than this? I know it is possible in the windows api but I would really like to use QT



  • Okay, after testing on multiple OS's, it works fine on linux but has the jitteryness on the top and left on widows. Also, I tried other boarderless windows apps that resize on the top and left are also jittery on windows.

    Is this a known qt bug?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.