若该文为原创文章,转载请注明原文出处
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/116292217 程序员
红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…(点击传送门)网络
上一篇:没有了
下一篇:敬请期待...框架
Qt中的拽拖操做详细介绍。函数
拖放提供了一种简单的可视机制,用户可使用它在应用程序之间和内部传输信息。拖放的功能相似于剪贴板的剪切和粘贴机制。
本文档描述了基本的拖放机制,并概述了在自定义控件中启用该机制的方法。许多qt的控件也支持拖放操做,例如项目视图和图形视图框架,以及为qt小部件和qt quick编辑控件。有关项目视图和图形视图的详细信息,请参见使用项目视图和图形视图框架的拖放。ui
这些类处理拖放和必要的mime类型编码和解码。
编码
QStyleHints对象提供了一些与拖放操做相关的属性:spa
若是在控件中提供拖放支持,这些数量将提供与基础窗口系统兼容的合理默认值,供您使用。.net
文档的其他部分主要关注如何在C++中实现拖放。要在Qt快速场景中使用拖放,请阅读Qt Quick拖放、DragEvent和DropArea项的文档,以及Qt快速拖放示例。翻译
要开始拖动,请建立一个QDrag对象,并调用其exec()函数。在大多数应用程序中,只有在按下鼠标按钮并移动光标必定距离后,才能开始拖放操做。可是,启用小部件拖动最简单方法是从新实现小部件的mousePressEvent(),并启动拖放操做:
尽管用户可能须要一些时间来完成拖动操做,但就应用程序而言,exec()函数是一个带有多个值之一的阻塞函数。这些说明操做是如何结束的,下面将详细介绍。
注意,exec()函数不会阻塞主事件循环。
对于须要区分鼠标单击和拖动的小部件,从新实现小部件的mousePressEvent()函数以记录拖动的开始位置是颇有用的:
对象
稍后,在mouseMoveEvent()中,咱们能够肯定是否应该开始拖动,并构造一个拖动对象来处理该操做:
这种特殊的方法使用QPoint::manhattanlength()函数粗略估计鼠标单击位置和当前光标位置之间的距离。此函数以精度换取速度,一般适用于此目的。
要可以接收小部件上丢弃的媒体,请为小部件调用setAcceptDrops(true),并从新实现dragEnterEvent()和dropEvent()事件处理程序函数。
例如,如下代码启用了QWidget子类的构造函数中的Drop事件,从而能够有效地实现Drop事件处理程序:
dragEnterEvent()一般用于通知qt小部件接受的数据类型。若是要在DragMoveEvent()和dropEvent()的从新实现中接收QDragMoveEvent或QDropEvent,则必须从新实现此函数。
报错
下面的代码显示如何从新实现DragEnterEvent(),以告诉拖放系统咱们只能处理纯文本:
dropEvent()用于解包丢弃的数据,并以适合您的应用程序的方式对其进行处理。
在如下代码中,事件中提供的文本将传递给QTextBrowser,QComboBox将填充用于描述数据的mime类型列表:
在这种状况下,咱们接受建议的操做,而不检查它是什么。在实际应用程序中,可能须要从dropEvent()函数返回,而不接受建议的操做,或者在操做不相关的状况下处理数据。例如,若是咱们不支持到应用程序中外部源的连接,咱们能够选择忽略Qt::LinkAction操做。
也能够忽略提议的操做,并对数据执行其余操做。为此,咱们将在调用accept()以前使用Qt::dropAction中的首选操做调用事件对象的setDropAction()。这样能够确保使用替换删除操做而不是建议的操做。
对于更复杂的应用程序,从新实现dragMoveEvent()和dragLeaveEvent()将使小部件的某些部分对放置事件敏感,并使您可以更好地控制应用程序中的拖放。
某些标准Qt小部件为拖放提供了本身的支持。在对这些小部件进行子类化时,除了DragCenterEvent()和DropEvent()以外,可能还须要从新实现DragMoveEvent(),以防止基类提供默认的拖放处理,并处理您感兴趣的任何特殊状况。
在最简单的状况下,拖放操做的目标将接收正在拖动的数据的副本,源将决定是否删除原始数据。这由CopyAction操做描述。目标还能够选择处理其余操做,特别是MoveAction和LinkAction操做。若是源调用QDrag::exec(),并返回MoveAction,则若是源选择删除任何原始数据,则该源将负责删除。不该删除源小部件建立的QMimeData和QDrag对象-它们将被Qt销毁。 目标负责获取在拖放操做中发送的数据的全部权;这一般经过保留对数据的引用来实现。
若是目标理解LinkAction操做,它应该存储本身对原始信息的引用;源不须要对数据执行任何进一步的处理。拖放操做的最多见用法是在同一个小部件中执行移动;有关此功能的详细信息,请参阅有关拖放操做的部分。
拖动操做的另外一个主要用途是在使用引用类型(如text/uri-list)时,其中拖动的数据其实是对文件或对象的引用。
拖放不限于文本和图像。任何类型的信息均可以在拖放操做中传输。要在应用程序之间拖动信息, 应用程序必须可以相互指示能够接受哪些数据格式以及能够生成哪些数据格式,这是经过使用mime类型实现的。 由源构造的QDrag对象包含一个用于表示数据的mime类型列表(从最合适的到最不合适的顺序排列),drop目标使用其中一个来访问数据。对于常见的数据类型,便利函数处理透明使用的mime类型,可是对于自定义数据类型,必须显式地声明它们。
要对QDrag便利功能未涵盖的信息类型执行拖放操做,第一步也是最重要的一步是查找适当的现有格式:Internet分配号码管理局(IANA)在信息科学研究所(ISI)提供了MIME媒体类型的分层列表。使用标准的mime类型能够最大限度地提升应用程序与其余软件如今和未来的互操做性。
要支持其余媒体类型,只需使用setData()函数设置QMimeData对象中的数据,提供完整的mime类型和以适当格式包含数据的QByteArray。如下代码从标签中获取QPixmap,并将其存储为QMimeData对象中的可移植网络图形(PNG)文件:
对于这种状况,咱们能够简单地使用setImageData()来提供各类格式的图像数据:
在这种状况下,QByteArray方法仍然颇有用,由于它能够更好地控制QMimeData对象中存储的数据量。
请注意,在项视图中使用的自定义数据类型必须声明为元对象,而且必须实现它们的流运算符。
在剪贴板模型中,用户能够剪切或复制源信息,而后粘贴它。一样,在拖放模型中,用户能够拖动信息的副本,也能够将信息自己拖动到新位置(移动信息)。拖放模型对于程序员来讲还有一个额外的复杂之处:在操做完成以前,程序不知道用户是否想要剪切或复制信息。在应用程序之间拖动信息时,这一般没有什么区别,但在应用程序中,检查使用了哪一个放置操做是很重要的。
能够为一个小部件从新实现mouseMoveEvent(),并经过可能的拖放操做组合启动拖放操做。例如,可能但愿确保拖动始终移动小部件中的对象:
若是信息被放到另外一个应用程序中,exec()函数返回的操做可能默认为copyAction,可是若是信息被放到同一个应用程序中的另外一个小部件中,咱们可能会得到不一样的drop操做。
能够在小部件的dragMoveEvent()函数中筛选建议的放置操做。可是,能够接受DragEnterEvent()中全部建议的操做,并让用户稍后决定要接受哪一个操做:
当小部件中发生放置时,将调用DropEvent()处理程序函数,咱们能够依次处理每一个可能的操做。首先,咱们在同一个小部件中处理拖放操做:
在这种状况下,拒绝处理移动操做。接受的每种类型的跌落动做都会进行相应的检查和处理:
注意,在上面的代码中检查了单独的放置操做。如上所述,在覆盖建议的操做部分,有时须要覆盖建议的删除操做,并从可能的删除操做中选择不一样的操做。为此,须要检查事件的possibleActions()提供的值中是否存在每一个操做,使用setDropAction()设置Drop操做,并调用accept()。
小部件的dragMoveEvent()可用于经过仅在光标位于这些区域内时接受建议的放置操做来限制小部件的某些部分的放置。例如,当光标位于子小部件(DropFrame)上时,如下代码接受任何建议的放置操做:
若是您须要在拖放操做期间提供视觉反馈、滚动窗口或任何适当的操做,也可使用DragMoveEvent()。
应用程序还能够经过将数据放在剪贴板上进行通讯。要访问这个,您须要从QApplication对象获取一个QClipboard对象。
QMimedata类用于表示在剪贴板中传输的数据。要将数据放在剪贴板上,可使用setText()、setImage()和setPixmap()方便函数来处理常见的数据类型。这些函数与在QMimedata类中找到的函数相似,只是它们还带有一个控制数据存储位置的附加参数:若是指定了剪贴板,则数据将放置在剪贴板上;若是指定了选择,则数据将放置在鼠标选择中(仅在x11上)。默认状况下,数据放在剪贴板上。
例如,咱们可使用如下代码将QLineEdit的内容复制到剪贴板:
具备不一样mime类型的数据也能够放在剪贴板上。构造一个qmimedata对象,并使用setData()函数按照前面部分描述的方式设置数据;而后可使用setmimedata()函数将该对象放到剪贴板上。
QClipboard类能够经过其dataChanged()信号通知应用程序它所包含的数据的更改。例如,咱们能够经过将此信号链接到小部件中的插槽来监视剪贴板:
链接到此信号的插槽可使用可用于表示该信号的MIME类型之一读取剪贴板上的数据:
selectionChanged()信号可用于x11以监视鼠标选择。
在x11上,使用公共XDND协议,而在Windows Qt上使用OLE标准,而Qt for MacOS使用Cocoa拖动管理器。在x11, XDND使用MIME,所以不须要翻译。不管平台如何,QT API都是相同的。在Windows上,支持MIME的应用程序可使用MIME类型的剪贴板格式名称进行通讯。一些Windows应用程序已经为其剪贴板格式使用了MIME命名约定。
用于转换专用剪贴板格式的自定义类能够经过在Windows上从新实现QwinMime或在MacOS上从新实现QMacPasteboardMime来注册。
上一篇:没有了
下一篇:敬请期待...
若该文为原创文章,转载请注明原文出处
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/116292217