当鼠标位于 Qt 中窗口的自定义小部件上时,如何移动整个窗口?

The*_*ang 2 c++ qt qwidget qt5 qmouseevent

假设我有一个自定义小部件并将其添加到 qt 的主窗口中。

在此处输入图片说明

如您所见,红色区域是自定义小部件。我想要做的是当鼠标在红色区域按下并移动时,整个窗口也会移动。

我知道如何简单地实现mousePressEventmouseMoveEvent;但是在处理带有自定义小部件的窗口时,我不知道如何在自定义小部件上按下鼠标时移动整个窗口。

另外我想提一下,我只希望在红色区域按下和移动鼠标时窗口可移动,当在主窗口区域的其余部分按下并移动鼠标时,什么都不会发生。

这是我的CustomWidget班级的样子:

CustomWidget::CustomWidget(QWidget *parent) : QWidget(parent)
{
    setFixedSize(50, 50);
    setStyleSheet("QWidget { background: red; }");
}

void CustomWidget::paintEvent(QPaintEvent *)
{
    QStyleOption opt;
    opt.init(this);
    QPainter painter(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
}

void CustomWidget::mousePressEvent(QMouseEvent *event)
{
    xCoord = event->x();
    yCoord = event->y();
}

void CustomWidget::mouseMoveEvent(QMouseEvent *event)
{
    move(event->globalX() - xCoord, event->globalY() - yCoord);
}
Run Code Online (Sandbox Code Playgroud)

如果你想知道我为什么要这样做,在我的应用程序中,我隐藏了标题栏并自己绘制了一个自定义标题栏。但是窗口是不可移动的,所以我想让整个窗口在鼠标在标题栏上按下和移动时都可以移动。
希望我清楚地解释了自己。

eyl*_*esc 5

要从任何小部件移动窗口,必须能够访问该窗口,为此我们使用window()返回顶层的方法,不需要将坐标x()和分开y(),以下代码实现了解决方案:

自定义小部件.h

#ifndef CUSTOMWIDGET_H
#define CUSTOMWIDGET_H

#include <QWidget>

class CustomWidget : public QWidget
{
    Q_OBJECT
public:
    explicit CustomWidget(QWidget *parent = nullptr);
protected:
    void paintEvent(QPaintEvent *);
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
private:
    QPoint startPos;
};

#endif // CUSTOMWIDGET_H
Run Code Online (Sandbox Code Playgroud)

customwidget.cpp

#include "customwidget.h"

#include <QMouseEvent>
#include <QPainter>
#include <QStyleOption>

CustomWidget::CustomWidget(QWidget *parent) : QWidget(parent)
{
    setFixedSize(50, 50);
    setStyleSheet("QWidget { background: red; }");
}

void CustomWidget::paintEvent(QPaintEvent *)
{
    QStyleOption opt;
    opt.init(this);
    QPainter painter(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
}

void CustomWidget::mousePressEvent(QMouseEvent *event)
{
    startPos = event->pos();
    QWidget::mousePressEvent(event);
}

void CustomWidget::mouseMoveEvent(QMouseEvent *event)
{
    QPoint delta = event->pos() - startPos;
    QWidget * w = window();
    if(w)
        w->move(w->pos() + delta);
    QWidget::mouseMoveEvent(event);
}
Run Code Online (Sandbox Code Playgroud)

  • *不需要*重新实现`paintEvent`。默认情况下,小部件绘制其背景。当你的 `paintEvent` 被调用时,背景已经绘制,它是红色的 :) 你还应该声明事件处理程序 `override`,因为你是用 C++11 编写的。 (2认同)