【问题标题】:Dragging a QWidget in QT 5在 QT 5 中拖动 QWidget
【发布时间】:2013-08-20 09:08:21
【问题描述】:

我必须制作类似 iOS 界面的东西,3x3 的图标字段可以拖动以更改其位置,然后将其记住在 XML 文件中。

我决定使用 Grid 类(QWidget 是父级)作为容器,而我自己的继承自 QWidget 的类作为元素。

现在我正在尝试学习如何为 QWidget 执行拖放操作,但您似乎只能拖放到 QWidget 上,但无法拖动它。

不可能吗?我该如何移动这个东西?

【问题讨论】:

标签: qt drag-and-drop qwidget


【解决方案1】:

拖动小部件并不容易。您必须自己完成大量编码。

来自Qt Docs

void MainWindow::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton
        && iconLabel->geometry().contains(event->pos())) {

        QDrag *drag = new QDrag(this);
        QMimeData *mimeData = new QMimeData;

        mimeData->setText(commentEdit->toPlainText());
        drag->setMimeData(mimeData);
        drag->setPixmap(iconPixmap);

        Qt::DropAction dropAction = drag->exec();
        ...
    }
}

这意味着,当您的小部件收到要拖动它的消息时,例如就像鼠标按下一样,它必须创建一个 QDrag 对象。

在 QDrag 对象中,您可以设置一个像素图,它代表您拖动的小部件。如果您此时隐藏您的小部件,看起来好像您的鼠标指针“占用”了小部件。

此外,您还需要一个 QMimeData 对象。您可以在其中放置各种数据,这些数据描述了您的小部件。在您的用例中,某些东西可以让您识别您的小部件。因为,困难的部分来了:你必须自己动手。

作为网格的父级的小部件接收到放置事件并从 mime 数据中读取,我希望移动哪个小部件。它从 QDropEvent 获取要移动小部件的点。这就是您必须编写的代码:网格布局中的实际重新定位。并且不要忘记更新 xml。

【讨论】:

  • 我只记得哪个元素正在移动,读取它被丢弃的其他元素,然后记住第二个,用第一个替换它,然后用 addWidget() 将第二个放在第一个的位置上和 removeWidget()?
  • @Leonid Bor,QDrag 对象为您提供了一种在鼠标指针下放置图标的方法。它提供了一种将有关拖动对象的数据传递给放置接收器的方法。如果您能以其他方式获得此信息……没问题。 addWidget() 和 removeWidget() 无疑是实际执行移动的一种方法。
【解决方案2】:

做一个技巧,你也可以拖动QWidget,

QPixmap *widgetPixmap = new QPixmap;
yourWidget->render(widgetPixmap); // rendering the current widget to t_iconTPixmap

现在使用这个widgetPixmap 作为yourDragObject->setPixmap(); 的像素图

例子,

void MainWindow::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton
    && iconLabel->geometry().contains(event->pos())) {

    QDrag *drag = new QDrag(this);
    QMimeData *mimeData = new QMimeData;

    mimeData->setText(commentEdit->toPlainText()); 

    QPixmap *widgetPixmap = new QPixmap;
    yourWidget->render(widgetPixmap);

    drag->setMimeData(mimeData);
    drag->setPixmap(widgetPixmap);

    Qt::DropAction dropAction = drag->exec();
    ...
   }
}

【讨论】:

  • 我收到一个错误:无法使用非活动画家进行渲染
  • 谢谢你的诡计。但作为我的尝试,我们需要使用new QPixmap(yourWidget.size())
【解决方案3】:

Qt wiki 包含一个 QtQuick 示例,介绍如何使用少于 80 行代码模拟 iOS 图标界面。

你可以找到它here

【讨论】:

  • 我认为,如果您阅读 qml,您可以将其翻译成 QGridLayout/QWidget 布局。毕竟,qml 只是另一种描述布局的语言。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-30
  • 1970-01-01
  • 1970-01-01
  • 2018-01-10
  • 1970-01-01
相关资源
最近更新 更多