关于以前的这篇博文,进行补坑
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();
}
}