使自定义 QLabel 可拖动 c++

问题描述 投票:0回答:1

我已经创建了一个自定义 QLabel 类,并试图使其可拖动。我已尽力而为,但未能如愿。我看到了很多相关问题,也尝试了chatgpt但无法得到想要的结果。除 DropEvent 外,所有事件都按预期调用。 qlabeldragdrop.h 定义了自定义类

#ifndef QLABELDRAGDROP_H
#define QLABELDRAGDROP_H

#include <QLabel>

class QLabelDragDrop : public QLabel
{
    Q_OBJECT
public:
    explicit QLabelDragDrop(QWidget *parent = nullptr);
protected:
    void mousePressEvent(QMouseEvent *event);
    void dragEnterEvent(QDragEnterEvent *event);
    void dragLeaveEvent(QDragLeaveEvent *event);
    void dragMoveEvent(QDragMoveEvent *event);
    void dropEvent(QDropEvent *event);
signals:

public slots:
};

#endif // QLABELDRAGDROP_H

以下是qlabeldragdrop.cpp中Custom QLabel类的声明

#include "qlabeldragdrop.h"
#include <QDebug>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QMimeData>
#include <QDrag>

void QLabelDragDrop::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        QPixmap pixmap("C:\\Users\\Farhan Ahmed\\Documents\\untitled\\drag.png");
        QMimeData *mimeData = new QMimeData;
        mimeData->setImageData(pixmap); // set the image data
        QDrag *drag = new QDrag(this);
        drag->setMimeData(mimeData); // set the mime data
        drag->setPixmap(pixmap); // set the pixmap
        drag->setHotSpot(event->pos());
        drag->exec(Qt::MoveAction | Qt::CopyAction);
    }
}


QLabelDragDrop::QLabelDragDrop(QWidget *parent) : QLabel(parent)
{
    setAcceptDrops(true);
    setMouseTracking(true);
}

void QLabelDragDrop::dragEnterEvent(QDragEnterEvent *event)
{
    qDebug() << "dragEnterEvent";
    event->acceptProposedAction();
}

void QLabelDragDrop::dragLeaveEvent(QDragLeaveEvent *event)
{
    qDebug() << "dragLeaveEvent";
    releaseMouse();
}

void QLabelDragDrop::dragMoveEvent(QDragMoveEvent *event)
{
    event->acceptProposedAction(); // accept the proposed action
    qDebug() << "dragMoveEvent";
}

void QLabelDragDrop::dropEvent(QDropEvent *event)
{
    event->acceptProposedAction();
    qDebug() << "dropEvent";
}


mainwindow.h有如下代码


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLabel>
#include <QPainter>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow

{
    Q_OBJECT
    int label_count = 0;
    QLabel *my_label = nullptr;
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void myAwesomeFunc();
    void drawLineBetweenLabelAndGroupBox(QLabel *label);

protected:
    void paintEvent(QPaintEvent* event) override;

private:
    Ui::MainWindow *ui;

};

#endif // MAINWINDOW_H

在 mainwindow.cpp 文件中,正在创建自定义 QLabel。


#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include "qlabeldragdrop.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QObject::connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::myAwesomeFunc);
}

MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::paintEvent(QPaintEvent* event) {
    QMainWindow::paintEvent(event);
    char c[] = "label_";
    //QString num = QString::number(label_count);
    //QString name = QString::fromUtf8(c, 6);
    //QLabel* my_label = ui->centralwidget->findChild<QLabel*>(name + num);

    if (my_label != nullptr){
        QPainter painter(this);
        painter.setPen(QPen(Qt::black, 2));
        QPoint start = my_label->frameGeometry().center();
        QPoint end = ui->groupBox->frameGeometry().center();
        painter.drawLine(start, end);
        label_count++;
    }
}

void MainWindow::myAwesomeFunc(){
    QLabelDragDrop *label = new QLabelDragDrop(ui->centralwidget);
    label->setGeometry(QRect(20,20,80,40));
    char c[] = "label_";
    QString num = QString::number(label_count);
    QString name = QString::fromUtf8(c, 6);
    label->setObjectName(name + num);
    label->setText("New Label");
    //label->setParent(ui->centralwidget);
    label->show();
    my_label = label;
    update();
}

main.cpp文件是


#include "mainwindow.h"

#include <QApplication>


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

我是 Qt 的新手,在 cpp 方面也没有太多经验。我已尽我最大的努力度过 3 天,但未能如愿。在此先感谢您的帮助。

c++ qt qlabel qt6
1个回答
0
投票

我第一眼就注意到的是,QLabel派生类有自己的鼠标事件方法,不应该的。这些鼠标事件需要在您要对其进行操作的小部件(例如主窗口)中被覆盖。

从这个example中得到一些启发,它与您想要的实现完全相同。

© www.soinside.com 2019 - 2024. All rights reserved.