Qt实现无边框窗口实现拉伸的三种方法--附源码

Qt实现无边框窗口实现拉伸的三种方法 最后一种比较推荐
希望能够对你起到帮助!!!代码都比较简短

1.重写下面mousePressEvent\ mouseMoveEvent mouseReleaseEvent事件

#include 
#include 
#include 

class ResizableWidget : public QWidget
{
public:
    ResizableWidget(QWidget *parent = nullptr) : QWidget(parent) {}

protected:
    void mousePressEvent(QMouseEvent *event) override
    {
        if (event->button() == Qt::LeftButton)
        {
            m_dragging = true;
            m_dragPos = event->pos();
        }
    }

    void mouseReleaseEvent(QMouseEvent *event) override
    {
        Q_UNUSED(event);
        m_dragging = false;
    }

    void mouseMoveEvent(QMouseEvent *event) override
    {
        if (m_dragging)
        {
            QPoint diff = event->pos() - m_dragPos;
            QSize sz = size() + QSize(diff.x(), diff.y());
            resize(sz);
        }
    }

private:
    bool m_dragging = false;
    QPoint m_dragPos;
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    ResizableWidget widget;
    widget.resize(400, 300);
    widget.show();

    return app.exec();
}

在这个示例中,我们创建了一个名为ResizableWidget的自定义QWidget,并重写了mousePressEvent()、mouseReleaseEvent()和mouseMoveEvent()事件。我们在mousePressEvent()中记录鼠标位置,并标记窗口正在被拖动。在mouseReleaseEvent()中,我们将拖动标记重置为false。在mouseMoveEvent()中,我们计算出鼠标移动的距离,并将其用于调整窗口的大小。

在主函数中,我们创建了一个ResizableWidget对象,并将其设置为窗口的大小和位置,并将其显示出来。

通过重写这些事件并处理窗口的大小和位置,我们可以在无边框窗口中实现拉伸。

2.QSizeGrip实现

#include 
#include 
#include 
#include 

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QWidget *widget = new QWidget;
    QVBoxLayout *layout = new QVBoxLayout(widget);
    widget->setLayout(layout);

    // 添加窗口内容
    // ...

    // 添加 QSizeGrip 控件
    QSizeGrip *sizeGrip = new QSizeGrip(widget);
    layout->addWidget(sizeGrip, 0, Qt::AlignBottom | Qt::AlignRight);

    // 设置窗口大小和位置
    widget->resize(400, 300);
    widget->move(100, 100);

    widget->show();

    return app.exec();
}

在这个示例中,我们首先创建一个QWidget对象和一个QVBoxLayout布局对象,并将布局设置为窗口的布局。然后,我们添加窗口的内容到布局中。

接下来,我们创建一个QSizeGrip对象,并将其添加到布局中的右下角。我们使用Qt::AlignBottom | Qt::AlignRight参数将QSizeGrip控件放置在窗口的右下角。

最后,我们设置窗口的大小和位置,并将其显示出来。

通过在无边框窗口中添加QSizeGrip控件,用户可以使用鼠标拖动控件来调整窗口的大小。

3.重写nativeEvent事件 比较推荐这种!!!

bool mainStructWin::nativeEvent(const QByteArray& eventType, void* message, long* result) {
    MSG* msg = static_cast<MSG*>(message);
    if (msg->message == WM_NCHITTEST) {
        *result = 0;
        const int BORDER_WIDTH = 8; // 拉伸边框的宽度
        RECT winrect;
        GetWindowRect(reinterpret_cast<HWND>(winId()), &winrect);
        long x = GET_X_LPARAM(msg->lParam);
        long y = GET_Y_LPARAM(msg->lParam);
        // 判断鼠标位置是否在拉伸区域内
        if (y < winrect.top + BORDER_WIDTH) {
            *result = HTTOP;
        }
        if (y > winrect.bottom - BORDER_WIDTH) {
            *result = HTBOTTOM;
        }
        if (x < winrect.left + BORDER_WIDTH) {
            *result = HTLEFT;
        }
        if (x > winrect.right - BORDER_WIDTH) {
            *result = HTRIGHT;
        }
        if (y < winrect.top + BORDER_WIDTH && x < winrect.left + BORDER_WIDTH) {
            *result = HTTOPLEFT;
        }
        if (y < winrect.top + BORDER_WIDTH && x > winrect.right - BORDER_WIDTH) {
            *result = HTTOPRIGHT;
        }
        if (y > winrect.bottom - BORDER_WIDTH && x < winrect.left + BORDER_WIDTH) {
            *result = HTBOTTOMLEFT;
        }
        if (y > winrect.bottom - BORDER_WIDTH && x > winrect.right - BORDER_WIDTH) {
            *result = HTBOTTOMRIGHT;
        }
        if (*result != 0) {
            return true;
        }
    }
    return QWidget::nativeEvent(eventType, message, result);
}

在Qt中,可以通过重写QWidget的nativeEvent()方法来实现无边框窗口的拉伸。nativeEvent()方法允许我们处理原生窗口系统事件,并在必要时将它们转换为Qt事件。

具体来说,我们可以使用WM_NCHITTEST和WM_GETMINMAXINFO消息来处理窗口的大小和最小化/最大化限制,以及WM_NCCALCSIZE消息来重新计算窗口的客户区大小和位置。此外,我们还需要处理WM_SYSCOMMAND消息,以便能够捕获窗口的系统命令,例如拖动、最小化、最大化和关闭。

使用nativeEvent()方法实现无边框窗口的拉伸需要深入了解Windows平台的窗口事件处理,以及如何将这些事件转换为Qt事件。因此,这种方法可能会比较复杂和容易出错。如果您不熟悉这些概念,建议使用Qt提供的内置的窗口框架,而不是手动处理原生窗口事件。

你可能感兴趣的:(QT,qt,开发语言)