咱們在編寫文本編輯器的時候,可能會但願其具備支持這種功能,將文件直接拖入文本編輯器打開。app
使用方法編輯器
- 1.包含頭文件
//拖拽事件 #include <QDragEnterEvent> //放下事件 #include <QDropEvent>
- 2.在類中加上以下聲明
- 1)void dragEnterEvent(QDragEnterEvent *event);
- 2)void dropEvent(QDropEvent *event);
class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private: Ui::MainWindow *ui; //複寫」拖拽事件「函數 void dragEnterEvent(QDragEnterEvent *event); //複寫」放下事件「函數 void dropEvent(QDropEvent *event); };
- 3.在類的構造函數中設置接受drop事件
//拖拽事件, 也就是能夠直接將要打開的文件, 拖入此窗口打開 this->setAcceptDrops(true);
- 4.複寫「拖拽事件」函數
void MainWindow::dragEnterEvent(QDragEnterEvent *event) { if(event->mimeData()->hasUrls()) { event->acceptProposedAction(); } else { event->ignore(); } }
- 5.複寫「放下事件」函數
void MainWindow::dropEvent(QDropEvent *event) { const QMimeData *mimeData = event->mimeData(); if(!mimeData->hasUrls()) { return; } QList<QUrl> urlList = mimeData->urls(); //若是同時拖入了多個資源,只選擇一個 QString fileName = urlList.at(0).toLocalFile(); if(fileName.isEmpty()) { return; } //打開拖入的文件 QFile file(fileName); if(!file.open(QIODevice::ReadOnly)) { QMessageBox::information(this, "錯誤", file.errorString(), QMessageBox::Ok); return; } //將文件內容放入文本框 QByteArray ba; ba = file.readAll(); ui->textEdit->setText(QString(ba)); }
- 6.效果
- 1)拖入mainWindow,也就是個人主窗口 <font color=red>這表示是成功的,注意這裏拖入的是mainWindow</font>
- 2)拖入textEdit和mainWindow的重疊區域 <font color=red>這裏顯然是失敗的,爲何會這樣?</font>
- 7.分析
查看官方幫助文檔,關於setAcceptDrops(bool on)有以下說明: acceptDrops : bool This property holds whether drop events are enabled for this widget Setting this property to true announces to the system that this widget may be able to accept drop events. If the widget is the desktop (windowType() == Qt::Desktop), this may fail if another application is using the desktop; you can call acceptDrops() to test if this occurs. Warning: Do not modify this property in a drag and drop event handler. By default, this property is false. Access functions: bool acceptDrops() const void setAcceptDrops(bool on)函數
關鍵的地方是:設置這個屬性有可能會失敗 <font color=red>個人窗口裏面有一個textEdit,textEdit也能接受drop事件,懷疑多是這個緣由</font>ui
- 8.解決 我在構造函數將textEdit接受drop事件禁用掉
//禁用textEdit的拖拽事件 ui->textEdit->setAcceptDrops(false);
至此,能愉快的拖放了。this
- 9.總結
1.這裏只是打開了mainWindow接受drop事件,而沒有打開textEdit接受drop事件。 2.就drop事件來講,默認是關閉的。 3.爲何textEdit的drop事件也被開啓了,致使mainWindow的drop事件沒觸發。 4.懷疑「事件過濾器」在mainWindow/widget等窗口控件上,設置接受某個事件後,窗口上的子控件也能接受該事件。 5.若是想只是觸發mainWindow的事件,而子部件不須要,則須要將子部件該事件禁用掉。