Qt - 控制拖动行为

发布于 2024-08-24 10:46:13 字数 95 浏览 4 评论 0原文

假设我希望可拖动小部件的移动方式不同于在拖动时仅停留在光标下方。例如,让小部件仅在一个轴上移动,或者让小部件移动光标与拖动起点之间距离的两倍。我应该重写哪个方法来定义这种行为?

Suppose I want my draggable widget to move differently than just staying under my cursor while being dragged. For instance, having the widget move only in one axis, or have the widget move double the distance between the cursor and the drag starting point. Which method should I override to define this kind of behaviour?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小清晰的声音 2024-08-31 10:46:13

我认为你应该问自己一个问题:你是否有一些我想要拖动到特定目标的可拖动元素(例如,你有代表不同形状的小部件,这些小部件应该拖动到代表孔的其他小部件上,并且每个“孔”仅接受相同形状的碎片)或者您只想将一个小部件移动到另一个小部件上?

如果您需要拖放放置功能,在我看来,您无法真正更改鼠标移动期间的行为 - 它或多或少被硬编码到 QDrag 对象中。

如果您只想移动东西,您应该只能通过重新实现鼠标移动/按下/释放事件来做到这一点(您可能还需要通过 QWidget::setMouseTracking 方法启用鼠标跟踪)。

编辑:

这是“只是移动东西”的可拖动标签的示例代码:

#ifndef DRAGGABLELABEL_H
#define DRAGGABLELABEL_H

#include <QLabel>
#include <QPoint>
#include <QMouseEvent>

class DraggableLabel : public QLabel
{
Q_OBJECT

public:
    explicit DraggableLabel(const QString &text, QWidget *parent = 0) : QLabel(text, parent) {}

protected:
    void mousePressEvent(QMouseEvent *event) {
        dragStart = event->pos();
    }

    void mouseMoveEvent(QMouseEvent *event) {
        setGeometry(QRect(geometry().topLeft() + event->pos() - dragStart, rect().size()));
    }

private:
    QPoint dragStart;

};

#endif // DRAGGABLELABEL_H

现在您只需将其添加到您的主小部件中:

#include <QApplication>
#include <QWidget>

#include "draggablelabel.h"

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

    QWidget mainWindow;

    DraggableLabel *label = new DraggableLabel("Test", &mainWindow);

    mainWindow.setMinimumSize(200, 200);
    mainWindow.show();

    return a.exec();
}

您可以尝试使用 moveMouseEvent 来实现仅在一个轴上拖动。

I think you should ask yourself a question: do you have some draggable elements I want to drag to specific targets (for example you have widgets that represent pieces of different shapes that should be dragged on other widgets representing holes and each "hole" accepts only pieces of the same shape) or do you just want to move one widget over the other widget?

If you need drag & drop functionality, it seems to me that you can't really change the behavior during mouse moving - it's more or less hardcoded into QDrag object.

If you just want to move stuff around, you should be able to do it only be reimplementing mouse Move/Press/Release events (you might also need to enable mouse tracking by QWidget::setMouseTracking method).

EDIT:

This is sample code for draggable label for "just moving stuff around":

#ifndef DRAGGABLELABEL_H
#define DRAGGABLELABEL_H

#include <QLabel>
#include <QPoint>
#include <QMouseEvent>

class DraggableLabel : public QLabel
{
Q_OBJECT

public:
    explicit DraggableLabel(const QString &text, QWidget *parent = 0) : QLabel(text, parent) {}

protected:
    void mousePressEvent(QMouseEvent *event) {
        dragStart = event->pos();
    }

    void mouseMoveEvent(QMouseEvent *event) {
        setGeometry(QRect(geometry().topLeft() + event->pos() - dragStart, rect().size()));
    }

private:
    QPoint dragStart;

};

#endif // DRAGGABLELABEL_H

Now you just need to add it to your main widget:

#include <QApplication>
#include <QWidget>

#include "draggablelabel.h"

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

    QWidget mainWindow;

    DraggableLabel *label = new DraggableLabel("Test", &mainWindow);

    mainWindow.setMinimumSize(200, 200);
    mainWindow.show();

    return a.exec();
}

You can experiment with moveMouseEvent to achieve dragging only in one axis.

倾`听者〃 2024-08-31 10:46:13

对于小部件,这四种方法控制拖动小部件的行为:

virtual void dragEnterEvent ( QDragEnterEvent * event )
virtual void dragLeaveEvent ( QDragLeaveEvent * event )
virtual void dragMoveEvent ( QDragMoveEvent * event )
virtual void dropEvent ( QDropEvent * event )

我想您必须重新实现 dragMoveEvent 才能实现您想要的效果。

For a widget these four methods control the behaviour of a dragged widget :

virtual void dragEnterEvent ( QDragEnterEvent * event )
virtual void dragLeaveEvent ( QDragLeaveEvent * event )
virtual void dragMoveEvent ( QDragMoveEvent * event )
virtual void dropEvent ( QDropEvent * event )

I guess you have to reimplement the dragMoveEvent to achieve what you want.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文