I haven't been writing a blog for a long time. I 've been helping my colleagues get a spring-mvc project. Today I 've finished my job, but I have to start flex 4 in the company, it may take some time! Next, the last time we talked about the drag and drop technology, today is still an example, also from C ++ GUI Programming with Qt 4, 2nd Edition. This demo is more practical: the implementation of data drag between two lists. This requirement is common in many projects! The following is an example! Projectlistwidget. h
- #ifndef PROJECTLISTWIDGET_H
- #define PROJECTLISTWIDGET_H
-
- #include <QtGui>
-
- class ProjectListWidget : public QListWidget
- {
- Q_OBJECT
-
- public:
- ProjectListWidget(QWidget *parent = 0);
-
- protected:
- void mousePressEvent(QMouseEvent *event);
- void mouseMoveEvent(QMouseEvent *event);
- void dragEnterEvent(QDragEnterEvent *event);
- void dragMoveEvent(QDragMoveEvent *event);
- void dropEvent(QDropEvent *event);
-
- private:
- void performDrag();
-
- QPoint startPos;
- };
-
- #endif // PROJECTLISTWIDGET_H
Projectlistwidget. cpp
- #include "projectlistwidget.h"
-
- ProjectListWidget::ProjectListWidget(QWidget *parent)
- : QListWidget(parent)
- {
- setAcceptDrops(true);
- }
-
- void ProjectListWidget::mousePressEvent(QMouseEvent *event)
- {
- if (event->button() == Qt::LeftButton)
- startPos = event->pos();
- QListWidget::mousePressEvent(event);
- }
-
- void ProjectListWidget::mouseMoveEvent(QMouseEvent *event)
- {
- if (event->buttons() & Qt::LeftButton) {
- int distance = (event->pos() - startPos).manhattanLength();
- if (distance >= QApplication::startDragDistance())
- performDrag();
- }
- QListWidget::mouseMoveEvent(event);
- }
-
- void ProjectListWidget::performDrag()
- {
- QListWidgetItem *item = currentItem();
- if (item) {
- QMimeData *mimeData = new QMimeData;
- mimeData->setText(item->text());
-
- QDrag *drag = new QDrag(this);
- drag->setMimeData(mimeData);
- drag->setPixmap(QPixmap(":/images/person.png"));
- if (drag->exec(Qt::MoveAction) == Qt::MoveAction)
- delete item;
- }
- }
-
- void ProjectListWidget::dragEnterEvent(QDragEnterEvent *event)
- {
- ProjectListWidget *source =
- qobject_cast<ProjectListWidget *>(event->source());
- if (source && source != this) {
- event->setDropAction(Qt::MoveAction);
- event->accept();
- }
- }
-
- void ProjectListWidget::dragMoveEvent(QDragMoveEvent *event)
- {
- ProjectListWidget *source =
- qobject_cast<ProjectListWidget *>(event->source());
- if (source && source != this) {
- event->setDropAction(Qt::MoveAction);
- event->accept();
- }
- }
-
- void ProjectListWidget::dropEvent(QDropEvent *event)
- {
- ProjectListWidget *source =
- qobject_cast<ProjectListWidget *>(event->source());
- if (source && source != this) {
- addItem(event->mimeData()->text());
- event->setDropAction(Qt::MoveAction);
- event->accept();
- }
- }
We can see from the constructor. Many components in Qt can be dragged and dropped, but the default actions are not allowed. Therefore, in the constructor, we call setAcceptDrops (true). This function allows the component to accept drag and drop events. In the mousePressEvent () function, click the left mouse button and record the current position. It should be noted that this function needs to call the built-in processing functions of the system in order to implement the common operation. This should be noted in some rewrite event functions! Then we overwrite the mouseMoveEvent () event. Next let's take a look at the Code:
- void ProjectListWidget::mouseMoveEvent(QMouseEvent *event)
- {
- if (event->buttons() & Qt::LeftButton) {
- int distance = (event->pos() - startPos).manhattanLength();
- if (distance >= QApplication::startDragDistance())
- performDrag();
- }
- QListWidget::mouseMoveEvent(event);
- }
Here we can determine that if you hold down the left button while dragging the mouse (that is, the content in the if), a manhattanLength () value will be calculated. Literally, this is a "Manhattan length ". What does this mean? Let's take a look at what event. pos ()-startPos is. Remember that in the mousePressEvent () function, we record the coordinates as startPos, and event. pos () is the current coordinate of the mouse: one point minus another. That's right. This is the vector! In fact, the so-called distance from Manhattan is the distance between two points (as to why this strange name is called, you will know it after checking encyclopedia !), That is, the length of the vector. The following is another judgment. If it is greater than QApplication: startDragDistance (), we will perform the drag operation. Of course, you still need to call the default mouse drag function. The significance of this judgment is to prevent the user from dragging the mouse due to factors such as hand jitter. The user must drag the mouse for a certain distance before we think that he wants to perform the drag operation, and this distance is provided by QApplication: startDragDistance (), which is usually 4px. Mongomdrag () starts the drag-and-drop process. We created a QDrag object and used this as the parent. QDrag uses QMimeData to store data. For example, we use the QMimeData: setText () function to store data of the text/plain type as a string. QMimeData provides many functions for storing data of URL and color types. You can use QDrag: setPixmap () to set the mouse style when dragging occurs. QDrag: exec () blocks the drag operation until the user completes the operation or cancels the operation. It accepts different types of actions as parameters, and the return value is the actually executed action. These actions are of the Qt: CopyAction, Qt: MoveAction, and Qt: LinkAction types. The return value has these three actions, and a Qt: IgnoreAction is added to indicate that the user has canceled the drag and drop operation. These actions depend on the types allowed by the drag-and-drop source object, the types accepted by the target object, and the keyboard keys that are pressed during the drag-and-drop. After exec () is called, Qt will delete the drag-and-drop object when it is not needed. ProjectListWidget can not only send drag events, but also accept data of different ProjectListWidget objects in the same application. In dragEnterEvent (), we use event-> source () to obtain such an object: If the drag-and-drop data comes from an object of the same type and comes from the same application, its pointer is returned, otherwise, NULL is returned. We use the qobject_cast macro to convert the pointer to the ProjectListWidget * type, and then set to accept the drag of the Qt: MoveAction type. DragMoveEvent () has the same code as this function, because we need to rewrite the code for dragging and moving. Finally, in the dropEvent () function, we retrieve the mimeData data in QDrag and call addItem () to add it to the current list. In this way, a relatively complete drag-and-drop code is complete. The drag-and-drop technology is a powerful technology in Qt, but it may be enough to simply implement the mouse event in a single component that does not involve data. You should consider it as needed!
This article is from the "bean space" blog, please be sure to keep this source http://devbean.blog.51cto.com/448512/286796