我正在尝试使用图形框架制作一个简单的可拖动项目。这是我到目前为止所做的代码:
小部件类:
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
};
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
DragScene *scene = new DragScene();
DragView *view = new DragView();
QHBoxLayout *layout = new QHBoxLayout();
DragItem *item = new DragItem();
view->setAcceptDrops(true);
scene->addItem(item);
view->setScene(scene);
layout->addWidget(view);
this->setLayout(layout);
}
Widget::~Widget()
{
}
DragView类:
class DragView : public QGraphicsView
{
public:
DragView(QWidget *parent = 0);
};
DragView::DragView(QWidget *parent) : QGraphicsView(parent)
{
setRenderHints(QPainter::Antialiasing);
}
DragScene类:
class DragScene : public QGraphicsScene
{
public:
DragScene(QObject* parent = 0);
protected:
void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
void dropEvent(QGraphicsSceneDragDropEvent *event);
};
DragScene::DragScene(QObject* parent) : QGraphicsScene(parent)
{
}
void DragScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event){
}
void DragScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event){
}
void DragScene::dragLeaveEvent(QGraphicsSceneDragDropEvent *event){
}
void DragScene::dropEvent(QGraphicsSceneDragDropEvent *event){
qDebug() << event->pos();
event->acceptProposedAction();
DragItem *item = new DragItem();
this->addItem(item);
// item->setPos(event->pos()); before badgerr's tip
item->setPos(event->scenePos());
}
DragItem类:
class DragItem : public QGraphicsItem
{
public:
DragItem(QGraphicsItem *parent = 0);
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
protected:
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
};
DragItem::DragItem(QGraphicsItem *parent) : QGraphicsItem(parent)
{
setFlag(QGraphicsItem::ItemIsMovable);
}
QRectF DragItem::boundingRect() const{
const QPointF *p0 = new QPointF(-10,-10);
const QPointF *p1 = new QPointF(10,10);
return QRectF(*p0,*p1);
}
void DragItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
if(painter == 0)
painter = new QPainter();
painter->drawEllipse(QPoint(0,0),10,10);
}
void DragItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event){
}
void DragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event){
}
void DragItem::mousePressEvent(QGraphicsSceneMouseEvent *event){
QMimeData* mime = new QMimeData();
QDrag* drag = new QDrag(event->widget());
drag->setMimeData(mime);
drag->exec();
}
void DragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event){
}
main.cpp实例化一个Widget并显示它。当我尝试拖动圆圈时,应用程序只会在原始圆圈上创建另一个圆圈,无论我在哪里释放拖动。 DragScene的dropEvent()中的qDebug()每次拖动结束时都会显示QPointF(0,0)。我很难完全理解我必须做什么,我应该将哪些类子类化,哪些方法需要重写,以使其工作。 documentation上的{{3}}不是很详细。我想知道如何使这项工作,如果有其他更全面的资源来了解图形视图框架,除了官方文档(这是非常好的btw,但如果有更详细的话会很好关于这个问题的论文。)
编辑:
根据badgerr的建议,我使用item-&gt; scenePos()替换了DragScene :: dropEvent()中的item-&gt; pos(),现在drop事件在drop网站中创建了一个新的圆圈,这或多或少我想要的是什么但是原始圆圈仍然存在,当拖动正在进行时,该项目不会跟随鼠标光标。
QGraphicsSceneDragDropEvent文档说pos()应该返回相对于发送事件的视图的光标位置,除非我弄错了,否则不应该一直是(0,0)。怪异。
我在一篇论坛帖子中看到你可以使用QDrag :: setPixMap()在拖动过程中显示一些内容,在示例中我看到图片被设置为pixmaps,但是我如何让像素图像我应该拖动的图形项目?
答案 0 :(得分:1)
有一个Qt助手的例子叫做“拖放机器人示例”,它似乎使用了QDrag方法,我不知道你是否已经看过它了。
编辑:只是快速观察一下,您似乎在DropEvent中创建了一个新的DragItem,而不是使用事件本身的mimeData(),并且因为您的项目将自己绘制为0, 0,这可以解释为什么你有一个新的出现在那个位置,无论你放置DragItem的位置。
当我写一个与此类似的图形拖动时,我采用了一种稍微不同的方式。也许它会对你有所帮助:
我没有使用QDrag的东西,只使用了QGraphicsItem的mousePressEvent,mouseReleaseEvent和mouseMoveEvent函数。鼠标按下/释放设置指示拖动状态的标志,然后按
的过程移动然后在我的paint()函数中,我使用boundingRect()绘制一个形状。
抱歉,我没有要分享的代码示例,如果我有时间,我会敲一下。