Как использовать mousePressEvent в 2 разных классах одновременно QT - PullRequest
0 голосов
/ 08 апреля 2019

Я занимаюсь разработкой программы, которая основана на 2 классах: Custom Label (отвечает за выдачу сигнала при наведении метки, показывая ее положение. Он также меняет курсор при нажатии на метку) и Widget (отвечает за функции перетаскивания, помимо возможности добавлять метки, когда я щелкаю в месте на экране).

Когда я запускаю программу, функция перетаскивания отключена. Я думаю, что причиной проблемы является тот факт, что в 2 классах одновременно используется одна и та же функция (mousePressEvent).

customlabel.cpp

#include "customlabel.h"
#include <QMouseEvent>

CustomLabel::CustomLabel(QWidget *parent):QLabel(parent)
{
    this->setMouseTracking(true);
    this->setCursor(Qt::OpenHandCursor);
}

void CustomLabel::mouseMoveEvent(QMouseEvent *event)
{
   QPoint mouse_pos=event->pos();


    if(mouse_pos.x()<=this->size().width() && mouse_pos.y()<=this->size().height()){

    if(mouse_pos.x()>0 && mouse_pos.y()>0){
          emit sendMousePosition(this->pos());
       }
    }
}

void CustomLabel::mousePressEvent(QMouseEvent *event)
{
   this->setCursor(Qt::ClosedHandCursor);
}

void CustomLabel::mouseReleaseEvent(QMouseEvent *event){
    this->setCursor(Qt::OpenHandCursor);
}

widget.cpp

void Widget::showMousePosition(const QPoint &pos)
{

    ui->label_show->setText("x"+QString::number(pos.x())+"y"+QString::number(pos.y()));
}


void Widget::dragEnterEvent(QDragEnterEvent *event)
{
    if (event->mimeData()->hasFormat("application/x-dnditemdata")) {
        if (event->source() == this) {
            event->setDropAction(Qt::MoveAction);
            event->accept();
        } else {
            event->acceptProposedAction();
        }
    } else {
        event->ignore();
    }
}

void Widget::dragMoveEvent(QDragMoveEvent *event)
{
    if (event->mimeData()->hasFormat("application/x-dnditemdata")) {
        if (event->source() == this) {
            event->setDropAction(Qt::MoveAction);
            event->accept();
        } else {
            event->acceptProposedAction();
        }
    } else {
        event->ignore();
    }
}

void Widget::dropEvent(QDropEvent *event)
{
    if (event->mimeData()->hasFormat("application/x-dnditemdata")) {
        QByteArray itemData = event->mimeData()->data("application/x-dnditemdata");
        QDataStream dataStream(&itemData, QIODevice::ReadOnly);

        QPixmap pixmap;
        QPoint offset;
        dataStream >> pixmap >> offset;

        CustomLabel *newIcon = new CustomLabel(this);
        newIcon->setPixmap(pixmap);
        newIcon->move(event->pos() - offset);
        newIcon->show();
        newIcon->setAttribute(Qt::WA_DeleteOnClose);
        connect(newIcon, &CustomLabel::sendMousePosition, this, &Widget::showMousePosition);

        if (event->source() == this) {
            event->setDropAction(Qt::MoveAction);
            event->accept();
        } else {
            event->acceptProposedAction();
        }
    } else {
        event->ignore();
    }
}


void Widget::mousePressEvent(QMouseEvent *event)
{


        if(event->button()==Qt::LeftButton){
            CustomLabel *child = static_cast<CustomLabel*>(childAt(event->pos()));

            if (!child)
                return;

            QPixmap pixmap = *child->pixmap();

            QByteArray itemData;
            QDataStream dataStream(&itemData, QIODevice::WriteOnly);
            dataStream << pixmap << QPoint(event->pos() - child->pos());

            QMimeData *mimeData = new QMimeData;
            mimeData->setData("application/x-dnditemdata", itemData);

            QDrag *drag = new QDrag(this);
            drag->setMimeData(mimeData);
            drag->setPixmap(pixmap);
            drag->setHotSpot(event->pos() - child->pos());

            QPixmap tempPixmap = pixmap;
            QPainter painter;
            painter.begin(&tempPixmap);
            painter.fillRect(pixmap.rect(), QColor(127, 127, 127, 127));
            painter.end();

            child->setPixmap(tempPixmap);

            if (drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction) == Qt::MoveAction) {
                child->close();
                connect(child, &CustomLabel::sendMousePosition, this, &Widget::showMousePosition);
            } else {
                child->show();
                child->setPixmap(pixmap);
                connect(child, &CustomLabel::sendMousePosition, this, &Widget::showMousePosition);
            }
        }
        else if(event->button()==Qt::RightButton)
        {

            CustomLabel *child = new CustomLabel(this);
            child->setPixmap(QPixmap("C:/Users/ILHA4/Desktop/paint5/trafo_png.png"));
            child->move(event->x(),event->y());
            child->show();
            connect(child, &CustomLabel::sendMousePosition, this, &Widget::showMousePosition);

        }

Как я могу использовать функции одновременно?

Как я могу это исправить?

1 Ответ

0 голосов
/ 08 апреля 2019

В вашем методе CustomLabel::mousePressEvent(QMouseEvent *event) вы можете отклонить событие.

Он будет отправлен родителю, и будет вызван CustomLabel::mousePressEvent(QMouseEvent *event) (см. Документация Qt ).

void CustomLabel::mousePressEvent(QMouseEvent *event)
{
    qDebug() << Q_FUNC_INFO;
    this->setCursor(Qt::ClosedHandCursor);
    event->ignore();
}

void Widget::mousePressEvent(QMouseEvent *event)
{
    qDebug() << Q_FUNC_INFO;
}

Вы увидите на панели вывода:

virtual void CustomLabel::mousePressEvent(QMouseEvent*)
virtual void Widget::mousePressEvent(QMouseEvent*)

Сделайте то же самое для других событий, которые вы хотите передать родителю.

...