Qt拖放 drag and drop
拖放提供一個應用程序之間傳遞信息的一種簡單的可視化機制。拖放機制類似于剪切和粘貼機制。拖放操作同時被QT項目視圖和圖形視圖框架支持。
QApplication提供了兩個拖放相關的方法:
1.?QApplication::startDragTime。它描述了用戶按下鼠標多長時間開始拖放操作。
2.?QApplication::startDragDistance。它描述了用戶按下鼠標移動多少像素才開始拖動。默認的是4個像素。
拖動操作drag:
為了開始一個拖動操作,需要創(chuàng)建一個QDrag對象,然后調(diào)用exec()函數(shù)。通常,在鼠標左鍵按下后并光標被移動了一定距離我們就開始一個拖動操作是個好主意,但是一個最簡單的方式是,讓一個重新實現(xiàn)了mousePressEvent()的窗口部件允許它拖動,然后開始拖放操作。例如:
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();
????????...
????}
}
QMimeData是記錄MIME類型信息的類,標準的MIME類型是有國際因特網(wǎng)地址分配委員會定義的,由類型,子類型信息和分隔兩者的斜線組成。MIME通常由剪貼板和拖放系統(tǒng)使用。QMimeData提供了一些可以用于處理最常見的拖動信息(例如圖像,URL,顏色,純文本,超文本)。setText()設置文本信息。將QMimeData對象存儲在QDrag對象里,并設置了隨光標移動的拖動圖片setPixmap()。QDrag::exec()啟動拖動操作。
通常我們要辨別點擊和拖動事件,那么要利用鼠標按下事件來獲取初始位置,再在鼠標移動事件里辨別是否響應拖動。
void?DragWidget::mousePressEvent(QMouseEvent?*event)
{
???if?(event->button()?==?Qt::LeftButton)
???????dragStartPosition?=?event->pos();
}
void?DragWidget::mouseMoveEvent(QMouseEvent?*event)
{
???if?(!(event->buttons()?&?Qt::LeftButton))
???????return;
???if?((event->pos()?-?dragStartPosition).manhattanLength()
????????<?QApplication::startDragDistance())
???????return;
???QDrag?*drag?=?new?QDrag(this);
???QMimeData?*mimeData?=?new?QMimeData;
???mimeData->setData(mimeType,?data);
???drag->setMimeData(mimeData);
???Qt::DropAction?dropAction?=?drag->exec(Qt::CopyAction?|?Qt::MoveAction);
???...
}
鼠標移動事件響應函數(shù)里manhattanLength()是曼哈頓長度,也就是鼠標按下到移動到當前光標位置的粗略長度值。startDragDistance()是先前提到的開始拖動距離默認是4像素。設置這樣的判斷可以過濾掉一些諸如點擊鼠標后不小心抖動的失誤操作。
放置操作drop:
為了接受一個放置操作,我們要為窗口部件調(diào)用setAcceptDrops(true)。并重實現(xiàn)dragEnterEvent()和dropEvent()事件處理函數(shù)。
例如,下面代碼為QWidget子類實現(xiàn)放置操作代碼:
Window::Window(QWidget?*parent)
????:?QWidget(parent)
{
???...
???setAcceptDrops(true);
}
void?Window::dragEnterEvent(QDragEnterEvent?*event)
{
???if?(event->mimeData()->hasFormat("text/plain"))
???????event->acceptProposedAction();
}
這里hasFormat通知只處理”text/plain”格式事件,acceptProposedAction通知接收目的活動,表明可以在這個部件上拖放對象。
void?Window::dropEvent(QDropEvent?*event)
{
???textBrowser->setPlainText(event->mimeData()->text());
???mimeTypeCombo->clear();
???mimeTypeCombo->addItems(event->mimeData()->formats());
???event->acceptProposedAction();
}
當將目標對象拖動放置到我們的這個Window窗口部件時,textBrowser設置文本,將之前保存的文本信息輸入到其中。清空mimeTypeCombo并添加一項。
我們可能會要忽略目的動作(action),而是執(zhí)行一個我們需要的其他動作。這時,我們需要調(diào)用setDropAction(),并附上我們需要的Qt::DropAction類型,再調(diào)用accept()。例如:
???event->setDropAction(Qt::MoveAction);
???event->accept();
在一些更為復雜的程序中,重新實現(xiàn)dragMoveEvent(),dragLeaveEvent()事件響應函數(shù),讓你的部件可以響應對鼠標放置和離開事件。不過大多數(shù)部件都已經(jīng)為我們實現(xiàn)好了。
下面給出一個實例,這是C++?GUI?QT4?編程?的例子。我截取重要的部分。
定義一個ProjectListWidget?類,為它實現(xiàn)拖動和放置操作。
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;
};
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::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();
???}
}
//?實現(xiàn)拖動
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;
???}
}
總結
以上是生活随笔為你收集整理的Qt拖放 drag and drop的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: centos7安装golang
- 下一篇: 引号不是字符串中唯一的可以被转义字符。下