Qt工作笔记-ListWidget拖动(拖拽)到QGraphicsScene【补坑】【Qt视图框架补坑】

关于以前的这篇博文,进行补坑

https://blog.csdn.net/qq78442761/article/details/80957186


坑的位置在这,采用上面这篇博文的配法,无法得到图元在场景中的坐标。

如下图:



原因是上篇博文,拖拽,是直接从ListWidget脱到场景中的。


而正在要实现的逻辑是,拖到视图中,然后视图再往场景放图元。而且,最好是对拖动的图像,也自定义下,这是为了重写,画图和边框的函数,用他自己带的,可以会出现莫名其妙的现象。


完成后,就可以获取图在场景中的坐标了,如下图所示:



程序结构图如下:



代码如下:

mygraphicslineitem.h

#ifndef MYGRAPHICSLINEITEM_H
#define MYGRAPHICSLINEITEM_H

#include <QGraphicsItem>

class MyGraphicsLineItem : public QGraphicsItem
{
public:
    MyGraphicsLineItem();
    ~MyGraphicsLineItem();

    QRectF boundingRect()const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
};

#endif // MYGRAPHICSLINEITEM_H

mygraphicsrectitem.h

#ifndef MYGRAPHICSRECTITEM_H
#define MYGRAPHICSRECTITEM_H

#include <QGraphicsItem>

class MyGraphicsRectItem : public QGraphicsItem
{
public:
    MyGraphicsRectItem();
    ~MyGraphicsRectItem();

    QRectF boundingRect()const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
};

#endif // MYGRAPHICSRECTITEM_H


mygraphicsscene.h

#ifndef MYGRAPHICSSCENE_H
#define MYGRAPHICSSCENE_H

#include <QObject>
#include <QGraphicsView>
class MyGraphicsScene : public QGraphicsScene
{
    Q_OBJECT
public:
    MyGraphicsScene(QWidget *parent=0);
    ~MyGraphicsScene();

    void createRect(const QPointF &pt);
    void createLine(const QPointF &pt);

protected:
    void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
    void dropEvent(QGraphicsSceneDragDropEvent* event);
    void dragMoveEvent(QGraphicsSceneDragDropEvent *event);

private:
    QGraphicsScene *m_scene;
};

#endif // MYGRAPHICSSCENE_H


mygraphicsview.h

#ifndef MYGRAPHICSVIEW_H
#define MYGRAPHICSVIEW_H

#include <QObject>
#include <QGraphicsView>

class MyGraphicsView : public QGraphicsView
{
public:
    MyGraphicsView(QWidget *parent=0);
    ~MyGraphicsView();

protected:
    void dragEnterEvent(QDragEnterEvent *event);
    void dropEvent(QDropEvent *event);

};

#endif // MYGRAPHICSVIEW_H


mylistwidget.h

#ifndef MYLISTWIDGET_H
#define MYLISTWIDGET_H

#include <QObject>
#include <QListWidget>

class MyListWidget:public QListWidget
{
    Q_OBJECT
public:
    MyListWidget(QWidget *parent=0);
    ~MyListWidget();

protected:
    void mouseMoveEvent(QMouseEvent *event);
    void mousePressEvent(QMouseEvent *event);

private:
    QPoint m_dragPosition; // 拖放起点
    QListWidgetItem *m_dragItem; // 被拖放的item
};

#endif // MYLISTWIDGET_H


widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class MyGraphicsScene;

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

public slots:
    void printBtnClicked();

private:
    Ui::Widget *ui;
    MyGraphicsScene *m_scene;
};


main.cpp

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}


mygraphicslineitem.cpp

#include "mygraphicslineitem.h"
#include <QPainter>
#include <QBrush>

MyGraphicsLineItem::MyGraphicsLineItem()
{

}

MyGraphicsLineItem::~MyGraphicsLineItem()
{

}

QRectF MyGraphicsLineItem::boundingRect() const
{
    qreal penWidth=1;
    return QRectF(0-penWidth/2,0-penWidth/2,4+penWidth,80+penWidth);
}

void MyGraphicsLineItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(option)
    Q_UNUSED(widget)

    painter->setBrush(Qt::red);
    painter->drawRect(0,0,4,80);
}


mygraphicsrectitem.cpp

#include "mygraphicsrectitem.h"
#include <QPainter>
#include <QDebug>
#include <QBrush>

MyGraphicsRectItem::MyGraphicsRectItem()
{

}

MyGraphicsRectItem::~MyGraphicsRectItem()
{

}

QRectF MyGraphicsRectItem::boundingRect() const
{
    qreal penWidth=1;
    return QRectF(0-penWidth/2,0-penWidth/2,18+penWidth,56+penWidth);
}

void MyGraphicsRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(option)
    Q_UNUSED(widget)
    painter->setBrush(Qt::red);
    painter->drawRect(0,0,18,56);
}


mygraphicsscene.cpp

#include "mygraphicsscene.h"
#include <QDebug>
#include <QMimeData>
#include <QGraphicsSceneDragDropEvent>
#include <QGraphicsLineItem>
#include <QGraphicsRectItem>
#include <QGraphicsScene>
#include <QPen>
#include "mygraphicslineitem.h"
#include "mygraphicsrectitem.h"


MyGraphicsScene::MyGraphicsScene(QWidget *parent):
    QGraphicsScene(parent)
{

}

MyGraphicsScene::~MyGraphicsScene()
{

}

void MyGraphicsScene::createRect(const QPointF &pt)
{
    MyGraphicsRectItem *item=new MyGraphicsRectItem;
    item->setPos(pt);
    item->setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
    addItem(item);
}

void MyGraphicsScene::createLine(const QPointF &pt)
{
    MyGraphicsLineItem *item=new MyGraphicsLineItem;
    item->setPos(pt);
    item->setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
    addItem(item);
}

void MyGraphicsScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
{
    if(event->mimeData()->hasFormat("text/plain")){
        event->acceptProposedAction();
    }
}

void MyGraphicsScene::dropEvent(QGraphicsSceneDragDropEvent *event)
{
    QGraphicsScene::dropEvent(event);
}

void MyGraphicsScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
{
    event->accept();
}


mygraphicsview.cpp

#include "mygraphicsview.h"
#include "mygraphicsscene.h"

#include <QDragEnterEvent>
#include <QMimeData>
#include <QDebug>

MyGraphicsView::MyGraphicsView(QWidget *parent):
    QGraphicsView(parent)
{

}

MyGraphicsView::~MyGraphicsView()
{

}


void MyGraphicsView::dragEnterEvent(QDragEnterEvent *event)
{
    if(event->mimeData()->hasFormat("text/plain")){
        event->acceptProposedAction();
    }

    QGraphicsView::dragEnterEvent(event);
}

void MyGraphicsView::dropEvent(QDropEvent *event)
{
    if (event->mimeData()->hasFormat("text/plain"))
    {

        QString text=event->mimeData()->text();
        MyGraphicsScene *scene=(MyGraphicsScene*)this->scene();
        if(text=="直线"){
            scene->createLine(mapToScene(event->pos()));
        }
        else if(text=="矩形"){
            scene->createRect(mapToScene(event->pos()));
        }
        else{

        }

        event->acceptProposedAction();
    }

    QGraphicsView::dropEvent(event);
}


mylistWidget.cpp

#include "mylistwidget.h"

#include <QMouseEvent>
#include <QListWidgetItem>
#include <QDrag>
#include <QApplication>
#include <QMimeData>
#include <QPainter>
#include <QPixmap>

MyListWidget::MyListWidget(QWidget *parent):
    QListWidget(parent)
{

}

MyListWidget::~MyListWidget(){

}

void MyListWidget::mouseMoveEvent(QMouseEvent *event){
    if(!(event->buttons()&Qt::LeftButton))
        return;
    if((event->pos()-m_dragPosition).manhattanLength()<QApplication::startDragDistance())
        return;
    if(!m_dragItem)
        return;
    QDrag *drag=new QDrag(this);
    QMimeData *mimeData=new QMimeData;
    mimeData->setText(currentItem()->text());
    drag->setMimeData(mimeData);

    if(mimeData->text()=="矩形"){
        QPixmap dragImg(18,50);
        QPainter painter(&dragImg);
        painter.setBrush(QBrush(Qt::red));
        painter.drawRect(0,0,18,50);
        drag->setPixmap(dragImg);
    }
    else if(mimeData->text()=="直线"){
        QPixmap dragImg(2,56);
        QPainter painter(&dragImg);
        painter.setPen(QPen(Qt::red,2));
        painter.drawLine(0,0,0,56);
        drag->setPixmap(dragImg);
    }
    else{

    }
    drag->exec(Qt::CopyAction|Qt::MoveAction);
}

void MyListWidget::mousePressEvent(QMouseEvent *event){
    m_dragPosition=event->pos();
    m_dragItem=this->itemAt(event->pos());

    //保持父类继承下来的按键行为
    QListWidget::mousePressEvent(event);
}


widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include "mygraphicsscene.h"

#include <QDebug>
#include <QGraphicsItem>
#include <QList>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    this->setWindowTitle("CSDN IT1995");

    QStringList strList;
    strList.append("矩形");
    strList.append("直线");
    ui->listWidget->insertItems(0,strList);
    ui->listWidget->setDragEnabled(true);

    m_scene=new MyGraphicsScene;
    ui->graphicsView->setScene(m_scene);

    connect(ui->printPushButton,&QPushButton::clicked,this,&Widget::printBtnClicked);

}

Widget::~Widget()
{
    delete ui;
}

void Widget::printBtnClicked()
{
    QList<QGraphicsItem*>listItem=m_scene->items();
    for(int i=0;i<listItem.size();i++){
        qDebug()<<"scenePos:"<<listItem[i]->scenePos();
    }
}


猜你喜欢

转载自blog.csdn.net/qq78442761/article/details/80996300