Drag the mouse to resize the window - Qt

Keywords: Qt

Transferred from: Qt - drag the mouse to adjust the window size - remove ice and sugar - blog Garden (cnblogs.com)

Requirement: when the mouse moves to the corner of the interface, the mouse style changes accordingly.

Implementation method 1:

Override mouseMoveEvent. If the mouse is not pressed, set the mouse style according to the position of the mouse on the interface. If the mouse is pressed, judge how to adjust the interface size or drag the interface according to the position. The idea is as above, and the implementation is very simple. However, there is a problem. If some other controls are placed in the interface, such as listWidget, and the mouse moves slightly faster at the edge of the interface, the mouseMoveEvent will be intercepted by the child controls, and the mouse style will not change. I haven't thought of a good solution to this problem.

ps:

Similar References: QT realizes dragging the mouse to adjust the window size_ Morning blog - CSDN blog

I encountered the situation that the mouse style would not change. I was still very confused at that time. The logic was right, but it was unsuccessful! Therefore, because the system only needs to support Windows, I want to find a way to realize this function through Windows (that is, method 2 below), and then I found this blog. The drawback is that the file download path of method 3 of this blog has failed. I hope I can supplement it when I have time!

Implementation method 2:

The specific implementation of handling windows events in Qt is as follows. Referring to some online contents, I modified and optimized it by the way. The source code is as follows:

#ifndef MBASEWIDGET_H

#define MBASEWIDGET_H



#include <QtWidgets/QWidget>

#include "windows.h"



class MBaseWidget : public QWidget

{

    Q_OBJECT



public:

    MBaseWidget(QWidget *parent);

    ~MBaseWidget();

    void setMarginWidth(const int &);           //Set the extent within which the mouse can drag the interface edge to change the interface size

    void serResizable(bool);                    //Sets whether you can drag to change the size



protected:

    bool nativeEvent(const QByteArray & eventType, void * message, long * result);

    bool winEvent(MSG *message, long *result);



private:

    int m_iMarginWidth;

    bool m_bCanResize;

};



#endif // MBASEWIDGET_H

#include "MBaseWidget.h"

#include "windowsx.h"



MBaseWidget::MBaseWidget(QWidget *parent)

    : QWidget(parent)

{

    m_iMarginWidth = 3;
    m_bCanResize = true;
    setWindowFlags(Qt::FramelessWindowHint);

}


MBaseWidget::~MBaseWidget()

{
}



void MBaseWidget::setMarginWidth(const int &iWidth)

{

    m_iMarginWidth = iWidth;

}

void MBaseWidget::serResizable(bool bCanResize)

{

    m_bCanResize = bCanResize;

}



//Handle windows events. In QT5, it is replaced by the function nativeEvent

bool MBaseWidget::winEvent(MSG *message, long *result)

{

    switch (message->message)

    {

    case WM_NCHITTEST:

        int iPosX = GET_X_LPARAM(message->lParam) - this->frameGeometry().x();//Mouse position x
        int iPosY = GET_Y_LPARAM(message->lParam) - this->frameGeometry().y();//Mouse position y



        *result = HTCAPTION;

        if (!m_bCanResize)

        {

            return true;//If true, you can still drag, but you cannot change the size

        }

         

        if (iPosX >= 0 && iPosX <= m_iMarginWidth)

        {

            *result = HTLEFT;//Left

            int iHeight = this->height();

            if (iPosY >= 0 && iPosY <= m_iMarginWidth)

            {
                *result = HTTOPLEFT;//Upper left

            }

            if (iPosY >= iHeight - m_iMarginWidth && iPosY <= iHeight)

            {
                *result = HTBOTTOMLEFT;//Lower left

            }

            return true;

        }



        int iWidth = this->width();

        int iHeight = this->height();

        if (iPosX >= iWidth - m_iMarginWidth && iPosX <= iWidth)

        {

            *result = HTRIGHT;//right

            if (iPosY >= 0 && iPosY <= m_iMarginWidth)

            {
                *result = HTTOPRIGHT;//Upper right
                return true;

            }

            if (iPosY >= iHeight - m_iMarginWidth && iPosY <= iHeight)

            {
                *result = HTBOTTOMRIGHT;//lower right
                return true;
            }
            return true;

        }

        if (iPosY >= 0 && iPosY <= m_iMarginWidth)

        {
            *result = HTTOP;//upper
            return true;
        }

        if (iPosY >= iHeight - m_iMarginWidth && iPosY <= iHeight)

        {

            *result = HTBOTTOM;//lower

            return true;
        }

        return true;
    }

    return false;

}



bool MBaseWidget::nativeEvent(const QByteArray &eventType, void *message, long *result)

{

    return winEvent((MSG*)message, result);

}

This method is implemented with the help of windows, so it is limited by the system. For example, when you drag and zoom in to the same size as the screen, you can't continue to zoom in, and there may be problems when other classes directly inherit this class.

Implementation method 3:

Since mouseMoveEvent cannot solve the problem of mouse style, you can consider implementing it through other events. The following is a class I implemented, including header files, dll and lib files.

You can configure it in project properties linker in VS. (the file download path is invalid ~, which is a pity, but it also provides an idea!)

Posted by onthespot on Mon, 01 Nov 2021 04:34:11 -0700