QT开发中文网

在Qt中实现拖拽按钮插入指定位置并重新排序

在Qt中实现拖拽按钮插入指定位置并重新排序的功能,可以通过重写事件处理函数来实现。以下是一个简单的示例,演示如何使用 QPushButton 进行拖放,并将其插入到新位置。

示例代码

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QMimeData>
#include <QMouseEvent>

class DraggableButton : public QPushButton {
    Q_OBJECT

public:
    DraggableButton(const QString &text, QWidget *parent = nullptr)
        : QPushButton(text, parent) {
        setAcceptDrops(true);
    }

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

    void mouseMoveEvent(QMouseEvent *event) override {
        if (event->buttons() & Qt::LeftButton) {
            if ((event->pos() - dragStartPosition).manhattanLength() >= QApplication::startDragDistance()) {
                QDrag *drag = new QDrag(this);
                QMimeData *mimeData = new QMimeData;
                mimeData->setText(text());
                drag->setMimeData(mimeData);
                
                // 设置拖动图标
                drag->setHotSpot(event->pos());
                drag->exec(Qt::MoveAction);
            }
        }
        QPushButton::mouseMoveEvent(event);
    }

private:
    QPoint dragStartPosition;
};

class DragDropWidget : public QWidget {
    Q_OBJECT

public:
    DragDropWidget() {
        setAcceptDrops(true);

        layout = new QVBoxLayout(this);

        for (int i = 0; i < 5; ++i) {
            DraggableButton *button = new DraggableButton(QString("Draggable Button %1").arg(i + 1), this);
            layout->addWidget(button);
        }

        setLayout(layout);
    }

protected:
    void dragEnterEvent(QDragEnterEvent *event) override {
        if (event->mimeData()->hasText()) {
            event->acceptProposedAction();
        }
    }

    void dropEvent(QDropEvent *event) override {
        QString text = event->mimeData()->text();
        
        // 在新的位置插入新按钮
        for (int i = 0; i < layout->count(); ++i) {
            QPushButton* button = qobject_cast<QPushButton*>(layout->itemAt(i)->widget());
            if (button && button->text() == text) { // 如果目标为同名按钮则跳过
                return;
            }
            
           // 获取当前鼠标的位置相对布局的位置
           QRect rect = button ? button->geometry() : QRect(0,0,0,0); 
           QPoint posInLayout = event->pos(); 

           // 检查如果鼠标在当前按钮上方就插入到该按钮前面
           if (rect.contains(posInLayout)) { 
               auto* droppedBtn = new DraggableButton(text, this); 
               layout->insertWidget(i, droppedBtn); // 插入新按钮到指定位置
               break;
           }
       }    
       event->acceptProposedAction(); // 接受放置操作
   }

private:
   QVBoxLayout* layout;
};

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

    DragDropWidget window;
    window.setWindowTitle("Draggable Buttons Example");
    window.resize(400, 300);

   window.show();

   return app.exec();
}

#include "main.moc"

说明

  1. DraggableButton 类:继承自 QPushButton,重写了 mousePressEventmouseMoveEvent 方法以支持拖动。在鼠标按下时记录位置,并在移动超过一定距离后开始拖动。

  2. DragDropWidget 类

    • 在构造函数中创建多个可拖动的按钮。
    • 重写 dragEnterEventdropEvent 方法以处理按钮的放置操作。当检测到鼠标放置的位置与某个现有按钮重合时,将新按钮插入该位置之前。
  3. 动态更新布局:每次拖放之后,新添加的按钮会自动加入到垂直布局中,并根据新的顺序排列其他已有的控件。

编译和运行

确保您已经安装了Qt开发环境,将上述代码复制到新的Qt项目中,然后编译运行。这段代码将创建一个窗口,其中包含多个可以被拖动的新按钮。当您将现有的按钮移动到新的位置时,它们会被重新排序并保持原来的交互性。


内容由零声教学AI助手提供,问题来源于学员提问

目录导航
  • 示例代码
  • 说明
  • 编译和运行
  • 本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
    转载请注明出处:https://qt.0voice.com/?id=13252

    分享:
    扫描分享到社交APP
    上一篇
    下一篇
    发表列表
    游客 游客
    此处应有掌声~
    评论列表

    还没有评论,快来说点什么吧~

    联系我们

    在线咨询: 点击这里给我发消息

    微信号:3007537140

    上班时间: 10:30-22:30

    关注我们
    x

    注册

    已经有帐号?